file preparation

PimpBig2 experiment analysis - loading the data

setwd("/Users/magdalena/Dropbox/DataAndAnalysis/Tomato/PimpiBIG csv raw files/")
list.files()
 [1] "20201112_PimpiBig2_analysis.Rmd"                                      
 [2] "20210203_PimpiBig_analysis.nb.html"                                   
 [3] "20210203_PimpiBig_analysis.Rmd"                                       
 [4] "all_trait_clusters_control.txt"                                       
 [5] "all_trait_clusters.txt"                                               
 [6] "Fig.Growth_rates_histograms_MR_noLR_aLRL.pdf"                         
 [7] "Fig.Lateral_root_distribution_across_MRL_DAS1_DAS4_Big01_to_Big04.pdf"
 [8] "Fig.STI_based_clusters_STI_trait_comparison.pdf"                      
 [9] "Fig.STI_clustering.pdf"                                               
[10] "Fig.TRS_MRL_LRL_LRno_CoG_MRLpTRS_Big01_to_Big04.pdf"                  
[11] "for_Arjun"                                                            
[12] "pimpi_Big1_D0_D1.csv"                                                 
[13] "pimpi_Big1_D1_D2.csv"                                                 
[14] "pimpi_Big1_D2_D3.csv"                                                 
[15] "pimpi_Big1_D4_D5.csv"                                                 
[16] "pimpi_BIG2_arbor_stats.csv"                                           
[17] "pimpi_Big2_D0_D1.csv"                                                 
[18] "pimpi_Big2_D2_D3.csv"                                                 
[19] "pimpi_Big2_D4_D5.csv"                                                 
[20] "pimpi_Big2_manual-scoring-last-day.csv"                               
[21] "pimpi_Big3_D0_D1.csv"                                                 
[22] "pimpi_Big3_D2_D3.csv"                                                 
[23] "pimpi_Big3_D3_D4.csv"                                                 
[24] "pimpi_Big3_D4_D5.csv"                                                 
[25] "pimpi_Big4_D0_D1.csv"                                                 
[26] "pimpi_Big4_D0_FU.csv"                                                 
[27] "pimpi_Big4_D0.csv"                                                    
[28] "pimpi_Big4_D2_D3.csv"                                                 
[29] "pimpi_Big4_D3_D4.csv"                                                 
[30] "pimpi_Big4_D4_D5.csv"                                                 
[31] "STI_clusters_better.txt"                                              
[32] "STI_clusters.txt"                                                     
Big1_D0D1 <- read.csv("pimpi_Big1_D0_D1.csv")
Big1_D2D3 <- read.csv("pimpi_Big1_D2_D3.csv")
Big1_D4D5 <- read.csv("pimpi_Big1_D4_D5.csv")

Big2_D0D1 <- read.csv("pimpi_Big2_D0_D1.csv")
Big2_D2D3 <- read.csv("pimpi_Big2_D2_D3.csv")
Big2_D4D5 <- read.csv("pimpi_Big2_D4_D5.csv")

Big3_D0D1 <- read.csv("pimpi_Big3_D0_D1.csv")
Big3_D2D3 <- read.csv("pimpi_Big3_D2_D3.csv")
Big3_D4D5 <- read.csv("pimpi_Big3_D4_D5.csv")

Big4_D0D1 <- read.csv("pimpi_Big4_D0_D1.csv")
Big4_D0_FU <- read.csv("pimpi_Big4_D0_FU.csv")
Big4_D2D3 <- read.csv("pimpi_Big4_D2_D3.csv")
Big4_D4D5 <- read.csv("pimpi_Big4_D4_D5.csv")

head(Big4_D0D1)
head(Big4_D0_FU)
# Need to add this because otherwise we have images that are called exactly the same and it is causing problems later on 
Big4_D0_FU$image <- gsub(".rsml", "_FU.rsml", Big4_D0_FU$image)
head(Big4_D0_FU)
head(Big4_D2D3)
head(Big4_D4D5)

Let’s fuse all the files into one big file per experiment

Big1 <- rbind(Big1_D0D1, Big1_D2D3)
Big1 <- rbind(Big1, Big1_D4D5)

Big2 <- rbind(Big2_D0D1, Big2_D2D3)
Big2 <- rbind(Big2, Big2_D4D5)

Big3 <- rbind(Big3_D0D1, Big3_D2D3)
Big3 <- rbind(Big3, Big3_D4D5)

Big4 <- rbind(Big4_D0D1, Big4_D0_FU)
Big4 <- rbind(Big4, Big4_D2D3)
Big4 <- rbind(Big4, Big4_D4D5)

Let’s make sure we have a collumn indicating the experimental batch as well:

Big1$experiment <- "Big01"
Big2$experiment <- "Big02"
Big3$experiment <- "Big03"
Big4$experiment <- "Big04"

There is an issue with the images from Big02 also being in Big04 - so we have to make sure that we have only images from particular experiment in there. So - we need to make a collumn for everyone with “date” to make sure we only have the following days

Big 1 experiment:

Big1$info <- strsplit(Big1$image, "_")
dim(Big1)
[1] 8555   21
Big1$date <- "none"
for(i in 1:8555){
  Big1$date[i] <- sapply(Big1$info[i], function(x){
  x[4]})
}
unique(Big1$date)
[1] "20190909" "20190910" "20190911" "20190912" "20190913"

Big 2 experiment:

Big2$info <- strsplit(Big2$image, "_")
dim(Big2)
[1] 13695    21
Big2$date <- "none"
for(i in 1:13695){
  Big2$date[i] <- sapply(Big2$info[i], function(x){
  x[4]})
}
unique(Big2$date)
[1] "20190923" "20190924" "20190926" "20190925" "20190927"

Big 3 experiment:

Big3$info <- strsplit(Big3$image, "_")
dim(Big3)
[1] 13232    21
Big3$date <- "none"
for(i in 1:13232){
  Big3$date[i] <- sapply(Big3$info[i], function(x){
  x[4]})
}
unique(Big3$date)
[1] "20190930" "20191001" "20191002" "20191003" "20191004"

Big 4 experiment:

Big4$info <- strsplit(Big4$image, "_")
dim(Big4)
[1] 13346    21
Big4$date <- "none"
for(i in 1:13346){
  Big4$date[i] <- sapply(Big4$info[i], function(x){
  x[4]})
}
unique(Big4$date)
[1] "20191009" "20191008" "20191010" "20191012" "20191011"

Now we can fuse all the data into one:

all_data <- rbind(Big1, Big2)
all_data <- rbind(all_data, Big3)
all_data <- rbind(all_data, Big4)
dim(all_data)
[1] 48828    22

Then - we need to check how many “Root” values we have per unique image and how many “Lateral root” values we have. This will save us heaps of headache in the future

In total we have X many images

length(unique(all_data$image))
[1] 5521

and we have X many Main Roots - which should be the same as image number…

onlyMr <- subset(all_data, all_data$root_order == 0)
dim(onlyMr)
[1] 6661   22

… but it isn’t - so let’s figure which images have more MR per image than 1 and remove these specific values (or decide which one to remove :)

We need to make a file where: Col. A > image Col. B > # Root Col. C > # Lateral Root

names <- c(text="image", "MR.no", "LR.no")
check_table <- data.frame()

for (k in names) check_table[[k]] <- as.character()

Then - we will subset the entire dataset for one image and calculate how many MR and LR are there and integrate it into the table

i=1

uni <- subset(all_data, all_data$image == unique(all_data$image)[i])
uni
MR <- subset(uni, uni$root_order == 0)
LR <- subset(uni, uni$root_order == 1)

check_table[i,1] <- as.character(unique(uni$image))
check_table[i,2] <- dim(MR)[1]
check_table[i,3] <- dim(LR)[1]
check_table

Cool - now let’s loop it for all the images:


for (i in 2:5521) {
  uni <- subset(all_data, all_data$image == unique(all_data$image)[i])
  uni
  MR <- subset(uni, uni$root_order == 0)
  LR <- subset(uni, uni$root_order == 1)
  
  check_table[i,1] <- as.character(unique(uni$image))
  check_table[i,2] <- dim(MR)[1]
  check_table[i,3] <- dim(LR)[1]
}

check_table

Cool - now let’s fish out all the images where we have multiple MR:

suspicious <- subset(check_table, check_table$MR.no > 1)
dim(suspicious)
[1] 1130    3
suspicious

Let’s have a closer look at these suspicious images:

closer_look <- subset(all_data, all_data$image == suspicious$image[100])
closer_look2 <- subset(closer_look, closer_look$root_order == 0)
closer_look2

It looks like these double roots are just duplications - let’s see what happens when we remove exact duplicates using tidyverse package

library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ───────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.1     ✓ purrr   0.3.4
✓ tibble  3.0.1     ✓ dplyr   1.0.0
✓ tidyr   1.1.0     ✓ stringr 1.4.0
✓ readr   1.3.1     ✓ forcats 0.5.0
── Conflicts ──────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
all_data2 <- all_data %>% distinct()
length(unique((all_data2$image)))
[1] 5521
onlyMr2 <- subset(all_data2, all_data2$root_order == 0)
dim(onlyMr2)
[1] 5543   22

cool - so now we have majority of the images where the MR is simply duplicated - so let’s repeat the exercise from above again to identify what other images we have left over which have two MR:

names <- c(text="image", "MR.no", "LR.no")
check_table2 <- data.frame()

for (k in names) check_table2[[k]] <- as.character()

for (i in 1:5521) {
  uni <- subset(all_data2, all_data2$image == unique(all_data2$image)[i])
  MR <- subset(uni, uni$root_order == 0)
  LR <- subset(uni, uni$root_order == 1)
  
  check_table2[i,1] <- as.character(unique(uni$image))
  check_table2[i,2] <- dim(MR)[1]
  check_table2[i,3] <- dim(LR)[1]
}

suspicious <- subset(check_table2, check_table2$MR.no > 1)
suspicious

Let’s have a closer look at these images and their MRs:

closer_look <- subset(all_data2, all_data2$image == suspicious$image[1])
closer_look1 <- subset(closer_look, closer_look$root_order == 0)
closer_look1

closer_look <- subset(all_data2, all_data2$image == suspicious$image[22])
closer_look2 <- subset(closer_look, closer_look$root_order == 0)
closer_look2

OK - so clearly - we have something that wasnt classified as LR properly (as in case of closer_look1).

We can recognize the “mistake MR” by saying that the name would start with root_ but let’s see if this is the case for many of them:

onlyMr <- subset(all_data2, all_data2$root_order == 0)
unique(onlyMr$root_name)
   [1] " 288_2_C"  " 189_3_C"  " 214_2_S"  " 201_1_C"  " root_0"   " 292_3_S"  " 306_1_C"  " 288_1_C"  " 213_3_S" 
  [10] " 207_3_S"  " 212_1_S"  " 207_3_C"  " 199_1_S"  " 307_2_C"  " 282_3_C"  " 199_2_S"  " 298_3_S"  " 212_3_C" 
  [19] " 212_2_C"  " 278_1_S"  " 301_1_C"  " 201_1_S"  " 286_1_S"  " 287_1_S"  " 213_2_C"  " 220_2_C"  " 286_2_S" 
  [28] " 214_1_C"  " 286_2_C"  " 194_1_S"  " 212_1_C"  " 294_2_C"  " 213_1_C"  " 287_2_S"  " 285_2_S"  " 293_2_C" 
  [37] " 284_2_S"  " 195_3_C"  " 277_1_C"  " 285_3_S"  " 278_1_C"  " 300_1_S"  " 214_3_C"  " 196_2_S"  " 292_1_C" 
  [46] " 283_2_C"  " 201_2_S"  " 307_1_S"  " 279_1_S"  " 298_1_S"  " 293_3_S"  " 280_1_S"  " 194_3_S"  " 294_3_S" 
  [55] " 299_2_C"  " 291_2_S"  " 207_1_S"  " 298_3_C"  " 282_1_C"  " 285_3_C"  " 280_3_C"  " 307_3_C"  " 200_1_S" 
  [64] " 211_3_S"  " 308_3_C"  " 284_1_S"  " 298_1_C"  " 308_2_C"  " 197_3_S"  " 290_2_C"  " 287_1_C"  " 301_1_S" 
  [73] " 196_1_C"  " 284_2_C"  " 299_1_C"  " 220_3_C"  " 278_3_C"  " 293_2_S"  " 308_3_S"  " 207_1_C"  " 283_2_S" 
  [82] " 306_2_S"  " 280_1_C"  " 220_1_C"  " 200_3_S"  " 214_3_S"  " 213_2_S"  " 287_3_S"  " 195_3_S"  " 290_1_S" 
  [91] " 194_3_C"  " 194_1_C"  " 288_3_S"  " 195_2_C"  " 282_2_S"  " 290_3_C"  " 196_2_C"  " 200_2_S"  " 300_2_C" 
 [100] " 198_2_C"  " 211_1_C"  " 200_1_C"  " 285_2_C"  " 197_1_C"  " 288_2_S"  " 292_2_C"  " 308_1_S"  " 301_2_C" 
 [109] " 279_3_C"  " 299_3_S"  " 195_2_S"  " 294_2_S"  " 279_2_C"  " 289_2_S"  " 282_2_C"  " 301_3_S"  " 299_1_S" 
 [118] " 300_3_C"  " 197_2_C"  " 286_1_C"  " 298_2_C"  " 288_3_C"  " 194_2_S"  " 306_2_C"  " 213_3_C"  " 307_1_C" 
 [127] " 201_3_C"  " 291_1_S"  " 291_3_C"  " 277_2_S"  " 220_1_S"  " 2800_3_S" " 280_2_C"  " 196_1_S"  " 207_2_S" 
 [136] " 235_1_C"  " 279_1_C"  " 278_3_S"  " 199_2_C"  " 287_3_C"  " 195_1_S"  " 290_2_S"  " 306_3_S"  " 213_1_S" 
 [145] " 294_1_C"  " 294_1_S"  " 290_3_S"  " 306_3_C"  " 195_1_C"  " 199_3_C"  " 283_3_C"  " 278_2_S"  " 290_1_C" 
 [154] " 299_2_S"  " 197_3_C"  " 212_2_S"  " 211_2_S"  " 211_2_C"  " 293_3_C"  " 199_3_S"  " 199_1_C"  " 214_1_S" 
 [163] " 277_1_S"  " 197_1_S"  " 299_3_C"  " 292_3_C"  " 291_2_C"  " 198_1_S"  " 207_2_C"  " 220_2_S"  " 282_1_S" 
 [172] " 214_2_C"  " 285_1_S"  " 292_2_S"  " 194_2_C"  " 278_2_C"  " 291_1_C"  " 198_2_S"  " 286_3_S"  " 212_3_S" 
 [181] " 200_2_C"  " 220_3_S"  " 198_1_C"  " 200_3_C"  " 300_3_S"  " 284_1_C"  " 293_1_S"  " 283_1_C"  " 211_3_C" 
 [190] " 283_3_S"  " 201_2_C"  " 286_3_C"  " 306_1_S"  " 277_2_C"  " 293_4_C"  " 279_3_S"  " 283_1_S"  " 307_3_S" 
 [199] " 307_2_S"  " 211_1_S"  " 197_2_S"  " 308_2_S"  " 301_2_S"  " 288_1_S"  " 300_2_S"  " 282_3_S"  " 287_2_C" 
 [208] " 301_3"    " 291_3_S"  " 294_3_C"  " 198_3_S"  " root_1"   " 308_1_C"  " 201_3_S"  " 192_3_C"  " 171_3_C" 
 [217] " 147_3_C"  " 252_1_S"  " 252_3_S"  " 258_1_S"  " 166_1_C"  " 269_3_C"  " 064_1_C"  " 253_2_S"  " 264_2_S" 
 [226] " 193_1_S"  " 146_3_C"  " 141_2_C"  " 267_1_C"  " 256_3_S"  " 061_1_S"  " 062_2_S"  " 065_2_S"  " 251_3_S" 
 [235] " 064_1_S"  " 139_3_S"  " 141_1_S"  " 169_1_S"  " 083_3_S"  " 258_3_S"  " 138_1_C"  " 083_2_S"  " 192_1_C" 
 [244] " 172_2_S"  " 144_2_C"  " 168_1_S"  " 268_1_S"  " 147_2_C"  " 253_3_S"  " 193_1_C"  " 264_2_C"  " 165_2_S" 
 [253] " 138_3_S"  " 146_2_C"  " 258_2_S"  " 061_2_C"  " 065_3_S"  " 262_3_S"  " 140_3_C"  " 260_2_S"  " 170_3_C" 
 [262] " 141_1_C"  " 144_1_C"  " 142_4_S"  " 258_1_C"  " 259_1_C"  " 270_1_C"  " 139_1_S"  " 191_1_S"  " 168_3_S" 
 [271] " 272_2_C"  " 138_4_C"  " 269_3_S"  " 147_1_S"  " 165_1_S"  " 144_2_S"  " 255_1_S"  " 147_3_S"  " 138_4_S" 
 [280] " 170_1_S"  " 060_1_S"  " 272_3_S"  " 065_3_C"  " 260_2_C"  " 251_2_C"  " 269_1_C"  " 172_2_C"  " 262_3_C" 
 [289] " 261_1_S"  " 261_2_S"  " 192_3_S"  " 166_3_C"  " 168_3_C"  " 260_1_C"  " 167_1_S"  " 262_2_C"  " 066_2_S" 
 [298] " 253_2_C"  " 142_3_C"  " 060_3_S"  " 165_2_C"  " 066_2_C"  " 136_3_C"  " 251_1_S"  " 191_2_C"  " 142_3_S" 
 [307] " 140_2_S"  " 141_2_S"  " 143_1_S"  " 256_2_S"  " 139_2_C"  " 193_3_S"  " 143_2_C"  " 064_2_S"  " 262_1_C" 
 [316] " 251_3_C"  " 138_2_C"  " 165_1_C"  " 252_3_C"  " 139_2_S"  " 083_3_C"  " 166_1_S"  " 171_3_S"  " 262_4_C" 
 [325] " 167_1_C"  " 256_1_C"  " 264_1_C"  " 146_1_C"  " 259_3_S"  " 143_2_S"  " 136_2_C"  " 170_2_C"  " 146_2_S" 
 [334] " 192_2_C"  " 061_3_C"  " 255_2_C"  " 147_1_C"  " 259_2_C"  " 140_2_C"  " 169_2_C"  " 258_3_C"  " 146_3_S" 
 [343] " 169_3_S"  " 138_2_S"  " 061_1_C"  " 267_1_S"  " 170_3_S"  " 252_2_S"  " 141_3_C"  " 140_3_S"  " 060_2_S" 
 [352] " 166_3_S"  " 082_3_C"  " 136_1_C"  " 141_3_S"  " 168_2_C"  " 165_3_C"  " 270_2_S"  " 272_3_C"  " 193_3_C" 
 [361] " 256_2_C"  " 252_2_C"  " 140_1_C"  " 142_2_C"  " 170_2_S"  " 171_2_C"  " 144_3_C"  " 193_2_S"  " 262_2_S" 
 [370] " 144_1_S"  " 272_1_C"  " 259_3_C"  " 138_1_S"  " 191_3_S"  " 062_1_C"  " 083_1_S"  " 147_2_S"  " 172_1_C" 
 [379] " 252_1_C"  " 136_2_S"  " 170_1_C"  " 063_1_S"  " 260_3_C"  " 264_3_C"  " 142_4_C"  " 270_2_C"  " 256_3_C" 
 [388] " 140_1_S"  " 269_2_S"  " 065_1_C"  " 191_1_C"  " 066_1_S"  " 061_2_S"  " 171_2_S"  " 142_1_S"  " 082_3_S" 
 [397] " 256_1_S"  " 193_2_C"  " 253_1_C"  " 168_2_S"  " 253_1_S"  " 142_2_S"  " 259_2_S"  " 065_2_C"  " 169_2_S" 
 [406] " 143_1_C"  " 171_1_C"  " 264_3_S"  " 260_3_S"  " 060_3_C"  " 192_1_S"  " 171_1_S"  " 261_2_C"  " 169_1_C" 
 [415] " 258_2_C"  " 063_1_C"  " 261_3_C"  " 082_2_C"  " 083_2_C"  " 082_1_S"  " 259_1_S"  " 191_2_S"  " 169_3_C" 
 [424] " 168_1_C"  " 272_2_S"  " 172_3_C"  " 255_1_C"  " 061_3_S"  " 261_3_S"  " 138_3_C"  " 261_1_C"  " 139_3_C" 
 [433] " 136_3_S"  " 082_1_C"  " 264_1_S"  " 268_2_S"  " 082_2_S"  " 270_1_S"  " 172_1_S"  " 262_4_S"  " 269_2_C" 
 [442] " 253_3_C"  " 251_1_C"  " 191_3_C"  " 272_1_S"  " 262_1_S"  " 268_2_C"  " 192_2_S"  " 066_1_C"  " 144_3_S" 
 [451] " 251_2_S"  " 136_1_S"  " 142_1_C"  " 255_2_S"  " 166_2_S"  " 083_1_C"  " 267_2_C"  " 060_1_C"  " 268_3_C" 
 [460] " 146_1_S"  " 065_1_S"  " 165_3_S"  " 268_3_S"  " 269_1_S"  " 166_2_C"  " 260_1_S"  " 172_3_S"  " 060_2_C" 
 [469] " 139_1_C"  " root_5"   " 230_2_C"  " 174_1_S"  " 234_1_C"  " 245_3_S"  " 173_4_C"  " 236_3_S"  " 084_3_C" 
 [478] " 240_4_C"  " 229_4_C"  " 245_1_S"  " 236_4_C"  " 241_1_C"  " 231_2_S"  " 175_1_S"  " 176_3_S"  " 245_4_S" 
 [487] " 064_3_S"  " 228_1_C"  " 244_2_S"  " 244_1_S"  " 227_1_C"  " 237_1_C"  " 228_1_S"  " 174_3_C"  " 176_1_C" 
 [496] " 229_4_S"  " 274_1_C"  " 249_3_S"  " 090_3_S"  " 090_1_S"  " 247_2_S"  " 235_2_S"  " 091_4_C"  " 087_1_S" 
 [505] " 091_4_S"  " 090_3_C"  " 085_2_S"  " 227_2_C"  " 237_3_C"  " 228_2_C"  " 230_3_s"  " 175_4_C"  " 250_1_C" 
 [514] " 222_2_S"  " 093_3_S"  " 229_2_S"  " 239_4_C"  " 240_1_C"  " 229_3_S"  " 233_1_C"  " 250_4_S"  " 274_2_C" 
 [523] " 093_1_C"  " 091_1_C"  " 247_3_S"  " 088_1_C"  " 230_1_S"  " 234_2_C"  " 271_2_S"  " 173_1_C"  " 240_2_S" 
 [532] " 092_4_C"  " 084_1_S"  " 227_3_C"  " 084_1_C"  " 229_3_C"  " 221_1_S"  " 233_3_S"  " 088_2_S"  " 236_1_S" 
 [541] " 239_4_S"  " 236_2_S"  " 221_1_C"  " 247_4_S"  " 225_1_C"  " 234_1_S"  " 173_3_C"  " 233_2_C"  " 089_3_C" 
 [550] " 234_2_S"  " 225_1_S"  " 241_2_C"  " 084_3_S"  " 247_1_S"  " 245_3_C"  " 089_1_"   " 247_3_C"  " 239_3_C" 
 [559] " 244_3_S"  " 038_2_S"  " 250_3_S"  " 085_1_S"  " 176_1_S"  " 228_3_C"  " 234_3_S"  " 038_3_S"  " 273_1_S" 
 [568] " 248_1_C"  " 247_2_C"  " 298_2_S"  " 228_4_C"  " 248_4_C"  " 089_2_S"  " 274_3_C"  " 086_3_C"  " 231_2_C" 
 [577] " 239_1_C"  " 173_1_S"  " 085_3_S"  " 086_1_C"  " 085_2_C"  " 093_2_C"  " 228_2_S"  " 084_2_S"  " 231_3_C" 
 [586] " 273_3_C"  " 175_3_C"  " 176_2_S"  " 091_2_S"  " 271_1_C"  " 084_4_C"  " 273_2_C"  " 173_4_S"  " 240_4_S" 
 [595] " 228_3_S"  " 274_4_C"  " 239_1_S"  " 236_2_C"  " 084_2_C"  " 173_2_C"  " 230_2_S"  " 093_2_S"  " 093_4_C" 
 [604] " 092_1_C"  " 250_4_C"  " 240_3_C"  " 174_1_C"  " 038_1_S"  " 176_4_C"  " 092_3_C"  " 244_3_C"  " 176_2_C" 
 [613] " 240_2_C"  " 241_2_S"  " 274_1_S"  " 064_2_C"  " 088_1_S"  " 227_2_S"  " 240_1_S"  " 087_2_S"  " 221_2_C" 
 [622] " 088_3_C"  " 092_2_C"  " 174_3_S"  " 235_1_S"  " 090_2_S"  " 086_3_S"  " 086_1_S"  " 089_2_C"  " 249_2_S" 
 [631] " 176_4_S"  " 231_1_C"  " 092_3_S"  " 091_3_S"  " 093_3_C"  " 229_1_S"  " 175_2_S"  " 236_3_C"  " 087_3_C" 
 [640] " 092_2_S"  " 239_2_S"  " 248_2_C"  " 229_1_C"  " 250_3_C"  " 222_2_C"  " 225_2_C"  " 038_3_C"  " 222_1_S" 
 [649] " 274_4_S"  " 233_3_C"  " 230_1_C"  " 090_1_C"  " 236_4_S"  " 175_2_C"  " 248_1_S"  " 271_4_S"  " 064_3_C" 
 [658] " 175_1_C"  " 093_1_S"  " 249_2_C"  " 173_2_S"  " 087_4_C"  " 230_3_C"  " 225_2_S"  " 090_2_C"  " 273_1_C" 
 [667] " 247_1_C"  " 237_2_C"  " 084_4_S"  " 249_3_C"  " 239_2_C"  " 237_4_C"  " 237_3_S"  " 231_1_S"  " 271_1_S" 
 [676] " 239_3_S"  " 233_4_S"  " 271_2_C"  " 175_3_S"  " 087_4_S"  " 092_1_S"  " 233_1_S"  " 174_4_C"  " 038_1_C" 
 [685] " 174_4_S"  " 087_1_C"  " 228_4_S"  " 092_4_S"  " 231_3_S"  " 273_2_S"  " 176_3_C"  " 247_4_C"  " 248_4_S" 
 [694] " 245_2_S"  " 240_3_S"  " 241_3_C"  " 245_1_C"  " 091_1_S"  " 233_2_S"  " 241_1_S"  " 085_1_C"  " 174_2_S" 
 [703] " 089_4_C"  " 244_1_C"  " 087_2_C"  " 248_3_C"  " 227_3_S"  " 273_3_S"  " 250_2_C"  " 271_3_C"  " 273_4_C" 
 [712] " 222_1_C"  " 248_2_S"  " 249_1_S"  " 093_4_S"  " 271_3_S"  " 236_1_C"  " 089_3_S"  " 237_1_S"  " 248_3_S" 
 [721] " 229_2_C"  " 273_4_S"  " 091_2_C"  " 085_3_C"  " 175_4_S"  " 244_2_C"  " 088_2_C"  " 089_4_S"  " 271_4_C" 
 [730] " 086_2_S"  " 237_4_S"  " 227_1_S"  " 087_3_S"  " 089_1_S"  " 250_2_S"  " 274_2_S"  " 091_3_C"  " 038_2_C" 
 [739] " 174_2_C"  " 274_3_S"  " 234_3_C"  " 241_3_S"  " 233_4_C"  " 245_2_C"  " 237_2_S"  " 173_3_S"  " 086_2_C" 
 [748] " 249_1_C"  " 088_3_S"  " 230_3_S"  " 089_1_C"  " 250_1_S"  " 237_1_s"  " 031_3_S"  " 030_3_C"  " 103_4_S" 
 [757] " 028_3_S"  " 098_1_S"  " 055_2_S"  " 075_3_C"  " 059_4_C"  " 095_4_C"  " 101_1_S"  " 034_1_C"  " 002_1_C" 
 [766] " 030_2_S"  " 103_3_S"  " 056_3_S"  " 001_3_C"  " 099_3_C"  " 102_4_C"  " 012_3_C"  " 076_1_C"  " 098_1_C" 
 [775] " 079_1_C"  " 080_2_S"  " 104_3_S"  " 005_3_S"  " 080_1_S"  " 006_2_C"  " 102_3_C"  " 081_1_C"  " 101_2_C" 
 [784] " 096_1_C"  " 101_2_S"  " 058_4_C"  " 028_4_C"  " 059_3_S"  " 099_2_S"  " 104_3_C"  " 103_3_C"  " 079_4_C" 
 [793] " 030_1_S"  " 105_4_S"  " 040_1_C"  " 080_4_S"  " 029_3_C"  " 036_2_C"  " 058_1_C"  " 057_3_S"  " 035_4_C" 
 [802] " 040_1_S"  " 010_2_S"  " 094_3_C"  " 032_3_S"  " 011_1_C"  " 010_2_C"  " 074_4_C"  " 032_4_S"  " 056_2_C" 
 [811] " 103_1_S"  " 103_1_C"  " 022_4_C"  " 010_1_S"  " 102_2_S"  " 105_3_C"  " 081_2_S"  " 003_3_S"  " 056_2_S" 
 [820] " 095_1_S"  " 009_3_S"  " 011_4_S"  " 002_2_S"  " 106_1_S"  " 098_3_C"  " 058_2_S"  " 040_3_S"  " 103_2_S" 
 [829] " 075_2_C"  " 001_4_S"  " 009_2_S"  " 081_1_S"  " 057_1_C"  " 028_3_C"  " 033_2_C"  " 012_1_S"  " 006_3_C" 
 [838] " 080_1_C"  " 098_3_S"  " 094_2_C"  " 029_3_S"  " 058_4_S"  " 074_3_C"  " 095_4_S"  " 028_1_S"  " 013_3_C" 
 [847] " 097_1_S"  " 001_2_S"  " 031_1_S"  " 105_1_S"  " 040_2_C"  " 094_2_S"  " 007_2_C"  " 075_3_S"  " 013_2_S" 
 [856] " 074_4_S"  " 007_1_C"  " 006_3_S"  " 035_2_C"  " 008_1_S"  " 057_1_S"  " 007_3_C"  " 059_3_C"  " 076_3_C" 
 [865] " 012_3_S"  " 008_3_C"  " 007_1_S"  " 094_3_S"  " 099_4_C"  " 057_3_C"  " 099_1_C"  " 040_4_C"  " 035_2_S" 
 [874] " 029_4_S"  " 104_2_S"  " 030_2_C"  " 012_2_S"  " 103_4_C"  " 079_3_S"  " 105_3_S"  " 007_2_S"  " 032_2_C" 
 [883] " 012_4_S"  " 057_4_S"  " 013_1_C"  " 032_1_C"  " 055_2_C"  " 010_3_S"  " 009_2_C"  " 078_3_S"  " 099_1_S" 
 [892] " 001_1_C"  " 057_2_S"  " 098_4_S"  " 079_2_S"  " 056_3_C"  " 003_3_C"  " 031_2_C"  " 106_2_C"  " 001_2_C" 
 [901] " 005_3_C"  " 059_1_C"  " 096_2_S"  " 009_1_C"  " root_3"   " 081_3_C"  " 081_4_S"  " 059_2_C"  " 037_1_C" 
 [910] " 031_4_C"  " 038_4_C"  " 057_2_C"  " 057_4_C"  " 030_1_C"  " 078_1_C"  " 035_1_S"  " 029_1_C"  " 101_3_S" 
 [919] " 055_1_S"  " 008_1_C"  " 034_1_S"  " 005_2_S"  " 011_3_C"  " 095_2_S"  " 001_1_S"  " 055_3_C"  " 003_2_S" 
 [928] " 105_4_C"  " 104_4_S"  " 031_4_S"  " 102_4_S"  " 059_2_S"  " 013_2_C"  " 079_3_C"  " 009_3_C"  " 074_2_S" 
 [937] " 006_1_C"  " 010_1_C"  " 075_1_S"  " 008_3_S"  " 009_4_C"  " 104_1_S"  " 058_3_C"  " 008_4_C"  " 011_4_C" 
 [946] " 010_3_C"  " 078_1_S"  " 058_2_C"  " 029_1_S"  " 076_2_C"  " 099_4_S"  " 106_2_S"  " 075_1_C"  " 009_1_S" 
 [955] " 008_4_S"  " 095_3_C"  " 080_2_C"  " 099_2_C"  " 033_2_S"  " 074_1_S"  " 003_1_S"  " 002_1_S"  " 011_3_S" 
 [964] " 105_2_C"  " 059_4_S"  " 080_3_S"  " 055_3_S"  " 028_1_C"  " 008_2_S"  " 035_3_C"  " 011_2_C"  " 094_1_C" 
 [973] " 013_3_S"  " 034_2_C"  " 055_1_C"  " 056_1_S"  " 005_2_C"  " 005_4_C"  " 035_3_S"  " 028_2_S"  " 005_4_S" 
 [982] " 058_3_S"  " 104_2_C"  " 056_1_C"  " 101_4_S"  " 079_4_S"  " 012_2_C"  " 002_4_S"  " 101_4_C"  " 031_1_C" 
 [991] " 059_1_S"  " 105_1_C"  " 095_3_S"  " 097_1_C"  " 098_4_C"  " 008_2_C"  " 033_3_S"  " 029_4_C"  " 094_1_S" 
[1000] " 034_3_C" 
 [ reached getOption("max.print") -- omitted 83 entries ]

ok - so then we have to split the root name into individual tiers and select MR which start with “root_”:

all_data2$root_info <- strsplit(all_data2$root_name, "_")
dim(all_data2)
[1] 41317    23
for(i in 1:41317){
  all_data2$genotype[i] <- sapply(all_data2$root_info[i], function(x){
  x[1]})
  all_data2$rep[i] <- sapply(all_data2$root_info[i], function(x){
  x[2]})
  all_data2$cond[i] <- sapply(all_data2$root_info[i], function(x){
  x[3]})
}

head(all_data2)

Now we have to subset for Mr and look at their individual genotype information

onlyMr <- subset(all_data2, all_data2$root_order == 0)
dim(onlyMr)
[1] 5543   26
unique(onlyMr$genotype)
  [1] " 288"  " 189"  " 214"  " 201"  " root" " 292"  " 306"  " 213"  " 207"  " 212"  " 199"  " 307"  " 282"  " 298" 
 [15] " 278"  " 301"  " 286"  " 287"  " 220"  " 194"  " 294"  " 285"  " 293"  " 284"  " 195"  " 277"  " 300"  " 196" 
 [29] " 283"  " 279"  " 280"  " 299"  " 291"  " 200"  " 211"  " 308"  " 197"  " 290"  " 198"  " 289"  " 2800" " 235" 
 [43] " 192"  " 171"  " 147"  " 252"  " 258"  " 166"  " 269"  " 064"  " 253"  " 264"  " 193"  " 146"  " 141"  " 267" 
 [57] " 256"  " 061"  " 062"  " 065"  " 251"  " 139"  " 169"  " 083"  " 138"  " 172"  " 144"  " 168"  " 268"  " 165" 
 [71] " 262"  " 140"  " 260"  " 170"  " 142"  " 259"  " 270"  " 191"  " 272"  " 255"  " 060"  " 261"  " 167"  " 066" 
 [85] " 136"  " 143"  " 082"  " 063"  " 230"  " 174"  " 234"  " 245"  " 173"  " 236"  " 084"  " 240"  " 229"  " 241" 
 [99] " 231"  " 175"  " 176"  " 228"  " 244"  " 227"  " 237"  " 274"  " 249"  " 090"  " 247"  " 091"  " 087"  " 085" 
[113] " 250"  " 222"  " 093"  " 239"  " 233"  " 088"  " 271"  " 092"  " 221"  " 225"  " 089"  " 038"  " 273"  " 248" 
[127] " 086"  " 031"  " 030"  " 103"  " 028"  " 098"  " 055"  " 075"  " 059"  " 095"  " 101"  " 034"  " 002"  " 056" 
[141] " 001"  " 099"  " 102"  " 012"  " 076"  " 079"  " 080"  " 104"  " 005"  " 006"  " 081"  " 096"  " 058"  " 105" 
[155] " 040"  " 029"  " 036"  " 057"  " 035"  " 010"  " 094"  " 032"  " 011"  " 074"  " 022"  " 003"  " 009"  " 106" 
[169] " 033"  " 013"  " 097"  " 007"  " 008"  " 078"  " 037" 
onlyMr$genotype <- gsub(" ", "", onlyMr$genotype)
unique(onlyMr$genotype)
  [1] "288"  "189"  "214"  "201"  "root" "292"  "306"  "213"  "207"  "212"  "199"  "307"  "282"  "298"  "278"  "301" 
 [17] "286"  "287"  "220"  "194"  "294"  "285"  "293"  "284"  "195"  "277"  "300"  "196"  "283"  "279"  "280"  "299" 
 [33] "291"  "200"  "211"  "308"  "197"  "290"  "198"  "289"  "2800" "235"  "192"  "171"  "147"  "252"  "258"  "166" 
 [49] "269"  "064"  "253"  "264"  "193"  "146"  "141"  "267"  "256"  "061"  "062"  "065"  "251"  "139"  "169"  "083" 
 [65] "138"  "172"  "144"  "168"  "268"  "165"  "262"  "140"  "260"  "170"  "142"  "259"  "270"  "191"  "272"  "255" 
 [81] "060"  "261"  "167"  "066"  "136"  "143"  "082"  "063"  "230"  "174"  "234"  "245"  "173"  "236"  "084"  "240" 
 [97] "229"  "241"  "231"  "175"  "176"  "228"  "244"  "227"  "237"  "274"  "249"  "090"  "247"  "091"  "087"  "085" 
[113] "250"  "222"  "093"  "239"  "233"  "088"  "271"  "092"  "221"  "225"  "089"  "038"  "273"  "248"  "086"  "031" 
[129] "030"  "103"  "028"  "098"  "055"  "075"  "059"  "095"  "101"  "034"  "002"  "056"  "001"  "099"  "102"  "012" 
[145] "076"  "079"  "080"  "104"  "005"  "006"  "081"  "096"  "058"  "105"  "040"  "029"  "036"  "057"  "035"  "010" 
[161] "094"  "032"  "011"  "074"  "022"  "003"  "009"  "106"  "033"  "013"  "097"  "007"  "008"  "078"  "037" 
onlyMr2 <- subset(onlyMr, onlyMr$genotype != "root")
dim(onlyMr2)
[1] 5520   26
unique(onlyMr2$genotype)
  [1] "288"  "189"  "214"  "201"  "292"  "306"  "213"  "207"  "212"  "199"  "307"  "282"  "298"  "278"  "301"  "286" 
 [17] "287"  "220"  "194"  "294"  "285"  "293"  "284"  "195"  "277"  "300"  "196"  "283"  "279"  "280"  "299"  "291" 
 [33] "200"  "211"  "308"  "197"  "290"  "198"  "289"  "2800" "235"  "192"  "171"  "147"  "252"  "258"  "166"  "269" 
 [49] "064"  "253"  "264"  "193"  "146"  "141"  "267"  "256"  "061"  "062"  "065"  "251"  "139"  "169"  "083"  "138" 
 [65] "172"  "144"  "168"  "268"  "165"  "262"  "140"  "260"  "170"  "142"  "259"  "270"  "191"  "272"  "255"  "060" 
 [81] "261"  "167"  "066"  "136"  "143"  "082"  "063"  "230"  "174"  "234"  "245"  "173"  "236"  "084"  "240"  "229" 
 [97] "241"  "231"  "175"  "176"  "228"  "244"  "227"  "237"  "274"  "249"  "090"  "247"  "091"  "087"  "085"  "250" 
[113] "222"  "093"  "239"  "233"  "088"  "271"  "092"  "221"  "225"  "089"  "038"  "273"  "248"  "086"  "031"  "030" 
[129] "103"  "028"  "098"  "055"  "075"  "059"  "095"  "101"  "034"  "002"  "056"  "001"  "099"  "102"  "012"  "076" 
[145] "079"  "080"  "104"  "005"  "006"  "081"  "096"  "058"  "105"  "040"  "029"  "036"  "057"  "035"  "010"  "094" 
[161] "032"  "011"  "074"  "022"  "003"  "009"  "106"  "033"  "013"  "097"  "007"  "008"  "078"  "037" 

Now - lets get rid of these bad MR from the original all_data2 file:

badMr <- subset(onlyMr, onlyMr$genotype == "root")
badMr
wrong_MR <- badMr$root
wrong_MR
 [1] " 506f645e-11ef-4f56-809d-b68535967791" " b6640da9-642f-4afe-8885-8aef081c64f2"
 [3] " 4db776d9-a41e-41db-95d3-5bbaf22712fa" " 4db776d9-a41e-41db-95d3-5bbaf22712fa"
 [5] " b671303e-fa10-4a09-b4ec-40d709f73703" " 1f9d1645-51c0-4c5d-9ef2-e15aacd51a65"
 [7] " 4db776d9-a41e-41db-95d3-5bbaf22712fa" " db20a3aa-2bc0-422d-bd9b-0c03f785f936"
 [9] " 4db776d9-a41e-41db-95d3-5bbaf22712fa" " 6c352368-f3d3-44a9-9d9b-1a6ac64b3636"
[11] " f2fa1001-0b9b-4714-ab14-9baec299245b" " e9280635-2275-4439-af3b-8d83ba551df1"
[13] " b6f9a393-91fa-40b8-b537-06a06ead5808" " a1c527ec-b83e-427b-8d3f-701df49f942f"
[15] " e93664ce-1b47-4d7b-821a-78b92049879c" " dd977aaa-fc38-4c4e-af58-fa3412af7478"
[17] " 049886f7-3a40-40b9-a4a9-160e7c2948d3" " 647a5d35-7a55-4281-8602-be4046f26ca1"
[19] " a3fa1354-196b-4b71-99fd-21545cb9e6aa" " 09d4bbd2-5f7f-4efe-a06e-aea8a173b02f"
[21] " cfa05ed0-4cca-4b09-8611-b315d8a8dc16" " 6b193102-e41c-401d-90ca-3278d1220e1e"
[23] " eecb776e-7fc2-4483-8a76-83b299756f67"
all_data2_single_MR <- all_data2[!(all_data2$root %in% wrong_MR),]
dim(all_data2_single_MR)
[1] 41276    26
dim(all_data2)
[1] 41317    26
length(unique((all_data2_single_MR$image)))
[1] 5520
onlyMr3 <- subset(all_data2_single_MR, all_data2_single_MR$root_order == 0)
dim(onlyMr3)
[1] 5513   26

So we still have 7 images that supposedly contain more than 2 roots

Let’s look at these images:

names <- c(text="image", "MR.no", "LR.no")
check_table2 <- data.frame()

for (k in names) check_table2[[k]] <- as.character()

for (i in 1:5520) {
  uni <- subset(all_data2_single_MR, all_data2_single_MR$image == unique(all_data2_single_MR$image)[i])
  MR <- subset(uni, uni$root_order == 0)
  LR <- subset(uni, uni$root_order == 1)
  
  check_table2[i,1] <- as.character(unique(uni$image))
  check_table2[i,2] <- dim(MR)[1]
  check_table2[i,3] <- dim(LR)[1]
}

suspicious <- subset(check_table2, check_table2$MR.no > 1)
suspicious
closer_look <- subset(all_data2_single_MR, all_data2_single_MR$image == suspicious$image[1])
closer_look1 <- subset(closer_look, closer_look$root_order == 0)
closer_look1

closer_look <- subset(all_data2_single_MR, all_data2_single_MR$image == suspicious$image[2])
closer_look2 <- subset(closer_look, closer_look$root_order == 0)
closer_look2

from the look of it - it seems we have two cases where we have exported twice the exact same root but one longer than the other (I presume longer is correct one). Problem is that their root and image are both identical.

After inspecting the images - it seems that: _set1_day3_20191002_238.tiff has > 2 lateral roots _set1_day3_20191002_001 has > 3 lateral roots

so in both cases - the 2nd Main Root is better. I am affraid that we will also get some oddness with positions of lateral roots. So maybe let’s inspect all the data belonging to these two images:

odd_stuff01 <- subset(all_data2_single_MR, all_data2_single_MR$image == "_set1_day3_20191002_238.rsml")
odd_stuff02 <- subset(all_data2_single_MR, all_data2_single_MR$image == "_set1_day3_20191002_001.rsml")
odd_stuff01
odd_stuff02

ok - so based on this data - it seems like: - the first 3 rows in odd_stuff01 are containing faulty data, and thus should be removed - the first 4 rows in odd_stuff02 are containing faulty data, and thus should be removed

So let’s remove these columns from individual odd_stuff files, remove the entire picture from the all_data2_single_MR, and then rbind() the odd_stuff together back into the all_data2_single_MR:

odd_stuff01 <- odd_stuff01[4:13,]
odd_stuff01

odd_stuff02 <- odd_stuff02[5:14,]
odd_stuff02

bye <- c("_set1_day3_20191002_238.rsml", "_set1_day3_20191002_001.rsml")
all_data3 <- subset(all_data2_single_MR, !(all_data2_single_MR$image %in% bye))
all_data3 <- rbind(all_data3, odd_stuff01)
all_data3 <- rbind(all_data3, odd_stuff02)

Let’s do a final check if we have NO other images that have two MR now:

length(unique(all_data3$image))
[1] 5520
names <- c(text="image", "MR.no", "LR.no")
check_table2 <- data.frame()

for (k in names) check_table2[[k]] <- as.character()

for (i in 1:5520) {
  uni <- subset(all_data3, all_data3$image == unique(all_data3$image)[i])
  MR <- subset(uni, uni$root_order == 0)
  LR <- subset(uni, uni$root_order == 1)
  
  check_table2[i,1] <- as.character(unique(uni$image))
  check_table2[i,2] <- dim(MR)[1]
  check_table2[i,3] <- dim(LR)[1]
}

suspicious <- subset(check_table2, check_table2$MR.no > 1)
suspicious

Great - no suspicious images anymore - so we can move on :)

calculating desired traits:

Let’s now get rid of all the traits like volume and diameter that we are not directly interested in:

head(all_data3)
colnames(all_data3)
 [1] "image"                 "root_name"             "root"                  "length"               
 [5] "surface"               "volume"                "diameter"              "root_order"           
 [9] "root_ontology"         "parent_name"           "parent"                "insertion_position"   
[13] "insertion_angle"       "n_child"               "child_density"         "first_child"          
[17] "insertion_first_child" "last_child"            "insertion_last_child"  "experiment"           
[21] "info"                  "date"                  "root_info"             "genotype"             
[25] "rep"                   "cond"                 
final <- all_data3[,c(1:3, 20, 22, 24:26, 4, 9, 11, 12,14,17,19)]
head(final)

then - we need to create a file that has all MR:

only_MR <- subset(final, final$root_ontology == unique(final$root_ontology)[1])
colnames(only_MR)[9] <- "MRL"
head(only_MR)

and since we dont need to calculate any LR related phenotypes for the plants that dont have LR - we need to subset our MR file a bit further:

no_LR_MR <- subset(only_MR, only_MR$n_child < 1)
only_MR <- subset(only_MR, only_MR$n_child > 0)
head(only_MR)
head(no_LR_MR)

Cool - there are now quite a lot of unneccessary information now - so let’s get to bare necessities:

colnames(only_MR)
 [1] "image"                 "root_name"             "root"                  "experiment"           
 [5] "date"                  "genotype"              "rep"                   "cond"                 
 [9] "MRL"                   "root_ontology"         "parent"                "insertion_position"   
[13] "n_child"               "insertion_first_child" "insertion_last_child" 
only_MR <- only_MR[,c(1:9,13:15)]
no_LR_MR <- no_LR_MR[,c(1:9,13:15)]
dim(only_MR)
[1] 4460   12
head(only_MR)

We have the same root ID occurring multiple times - as we are tracing individual plants accross the time and transferring the data from one image to another - therefore - let’s check if it all adds up:

all_MR <- unique(only_MR$root)
length(all_MR)
[1] 1289
all_img <- unique(only_MR$image)
length(all_img)
[1] 4460
length(all_img) / length(all_MR)
[1] 3.460047
only_MR$image_id <- paste(only_MR$image, "_", only_MR$root_name, sep="")
head(only_MR)

all_img_id <- unique(only_MR$image_id)
length(all_img_id)
[1] 4460

Almost - but we will deal with it later.

So we have in total 4460 unique images - we will have to examine the LR belonging to each MR in each image by extracting them based on the “date”:

MR_now <- all_img[4460]
MR_now
[1] "_set1_day3_20191002_001.rsml"
head(final)

super_temp <- subset(final, final$image %in% MR_now)
super_temp

Then - we need to create some info about the length of individual zones - for this we need info on MR_length:

MR_length <- subset(only_MR, only_MR$image %in% MR_now)
MR_length <- MR_length$MRL
MR_length
[1] 5.284145

Length of Apical zone is basically equal to position of first lateral root Branched zone length is the position of last LR - position of first LR Basal zone is the MR length - position of last LR thus:

super_temp <- subset(super_temp, super_temp$root_ontology == unique(super_temp$root_ontology)[2])
super_temp
Apical <- min(super_temp$insertion_position)
Branched <- (max(super_temp$insertion_position) - Apical)
Basal <- MR_length - max(super_temp$insertion_position)
Apical
[1] 0
Branched
[1] 2.728526
Basal
[1] 2.555619

Another thing that I am interested in is the distribution of LRL across the MR and how quickly that decreases across the MRL

super_temp
#super_temp$adj_position <- super_temp$insertion_position + 0.0000001
plot(super_temp$length ~ super_temp$insertion_position)
abline(lm(super_temp$length ~ super_temp$insertion_position))

model <- lm(super_temp$length ~ super_temp$insertion_position)
summary(model)

Call:
lm(formula = super_temp$length ~ super_temp$insertion_position)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.27974 -0.14623 -0.03718  0.27756  0.93525 

Coefficients:
                              Estimate Std. Error t value Pr(>|t|)   
(Intercept)                     1.7538     0.3756    4.67  0.00229 **
super_temp$insertion_position  -0.5973     0.2254   -2.65  0.03293 * 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.648 on 7 degrees of freedom
Multiple R-squared:  0.5009,    Adjusted R-squared:  0.4296 
F-statistic: 7.024 on 1 and 7 DF,  p-value: 0.03293
model$coefficients
                  (Intercept) super_temp$insertion_position 
                     1.753818                     -0.597283 
LRL.dec <- model$coefficients[[2]]
LRL.dec.R2 <- summary(model)$r.squared
LRL.dec.R2
[1] 0.5008563
LRL.dec
[1] -0.597283

Then - we can calculate the % of LR across the MR length - by dividing the MR into 4 or 10 parts

super_temp$LR_in_10_perc <- 0
super_temp$LR_in_20_perc <- 0
super_temp$LR_in_30_perc <- 0
super_temp$LR_in_40_perc <- 0
super_temp$LR_in_50_perc <- 0
super_temp$LR_in_60_perc <- 0
super_temp$LR_in_70_perc <- 0
super_temp$LR_in_80_perc <- 0
super_temp$LR_in_90_perc <- 0
super_temp$LR_in_100_perc <- 0


for(e in 1:nrow(super_temp)){
   if (super_temp$insertion_position[e] < (MR_length/10)){
    super_temp$LR_in_10_perc[e] <- 1
   } else {super_temp$LR_in_10_perc[e] <- 0}
  if (super_temp$insertion_position[e] < 2*(MR_length/10) & super_temp$insertion_position[e] > (MR_length/10)){
    super_temp$LR_in_20_perc[e] <- 1
  } else {super_temp$LR_in_20_perc[e] <- 0}
  if (super_temp$insertion_position[e] < 3*(MR_length/10) & super_temp$insertion_position[e] > 2*(MR_length/10)){
    super_temp$LR_in_30_perc[e] <- 1
  } else {super_temp$LR_in_30_perc[e] <- 0}
  if (super_temp$insertion_position[e] < 4*(MR_length/10) & super_temp$insertion_position[e] > 3*(MR_length/10)){
    super_temp$LR_in_40_perc[e] <- 1
  } else {super_temp$LR_in_40_perc[e] <- 0}
  if (super_temp$insertion_position[e] < 5*(MR_length/10) & super_temp$insertion_position[e] > 4*(MR_length/10)){
    super_temp$LR_in_50_perc[e] <- 1
  } else {super_temp$LR_in_50_perc[e] <- 0}
  if (super_temp$insertion_position[e] < 6*(MR_length/10) & super_temp$insertion_position[e] > 5*(MR_length/10)){
    super_temp$LR_in_60_perc[e] <- 1
  } else {super_temp$LR_in_60_perc[e] <- 0}
  if (super_temp$insertion_position[e] < 7*(MR_length/10) & super_temp$insertion_position[e] > 6*(MR_length/10)){
    super_temp$LR_in_70_perc[e] <- 1
  } else {super_temp$LR_in_70_perc[e] <- 0}
  if (super_temp$insertion_position[e] < 8*(MR_length/10) & super_temp$insertion_position[e] > 7*(MR_length/10)){
    super_temp$LR_in_80_perc[e] <- 1
  } else {super_temp$LR_in_80_perc[e] <- 0}
  if (super_temp$insertion_position[e] < 9*(MR_length/10) & super_temp$insertion_position[e] > 8*(MR_length/10)){
    super_temp$LR_in_90_perc[e] <- 1
  } else {super_temp$LR_in_90_perc[e] <- 0}
  if (super_temp$insertion_position[e] < 10*(MR_length/10) & super_temp$insertion_position[e] > 9*(MR_length/10)){
    super_temp$LR_in_100_perc[e] <- 1
  } else {super_temp$LR_in_100_perc[e] <- 0}
}

super_temp

so after classifying each LR to its respective portion of MR, we can then summarize them and calculate total LR length in this fragment:

super_temp$LRL_in_10_perc <- super_temp$length * super_temp$LR_in_10_perc
super_temp$LRL_in_20_perc <- super_temp$length * super_temp$LR_in_20_perc
super_temp$LRL_in_30_perc <- super_temp$length * super_temp$LR_in_30_perc
super_temp$LRL_in_40_perc <- super_temp$length * super_temp$LR_in_40_perc
super_temp$LRL_in_50_perc <- super_temp$length * super_temp$LR_in_50_perc
super_temp$LRL_in_60_perc <- super_temp$length * super_temp$LR_in_60_perc
super_temp$LRL_in_70_perc <- super_temp$length * super_temp$LR_in_70_perc
super_temp$LRL_in_80_perc <- super_temp$length * super_temp$LR_in_80_perc
super_temp$LRL_in_90_perc <- super_temp$length * super_temp$LR_in_90_perc
super_temp$LRL_in_100_perc <- super_temp$length * super_temp$LR_in_100_perc

LR_no_10_100 <- sum(super_temp$LR_in_10_perc)
LR_no_20_100 <- sum(super_temp$LR_in_20_perc)
LR_no_30_100 <- sum(super_temp$LR_in_30_perc)
LR_no_40_100 <- sum(super_temp$LR_in_40_perc)
LR_no_50_100 <- sum(super_temp$LR_in_50_perc)
LR_no_60_100 <- sum(super_temp$LR_in_60_perc)
LR_no_70_100 <- sum(super_temp$LR_in_70_perc)
LR_no_80_100 <- sum(super_temp$LR_in_80_perc)
LR_no_90_100 <- sum(super_temp$LR_in_90_perc)
LR_no_100_100 <- sum(super_temp$LR_in_100_perc)

LRL_10_100 <- sum(super_temp$LRL_in_10_perc)
LRL_20_100 <- sum(super_temp$LRL_in_20_perc)
LRL_30_100 <- sum(super_temp$LRL_in_30_perc)
LRL_40_100 <- sum(super_temp$LRL_in_40_perc)
LRL_50_100 <- sum(super_temp$LRL_in_50_perc)
LRL_60_100 <- sum(super_temp$LRL_in_60_perc)
LRL_70_100 <- sum(super_temp$LRL_in_70_perc)
LRL_80_100 <- sum(super_temp$LRL_in_80_perc)
LRL_90_100 <- sum(super_temp$LRL_in_90_perc)
LRL_100_100 <- sum(super_temp$LRL_in_100_perc)

OK - last but not least - we should calculate the center of gravity for LR:

super_temp$momentum <- (super_temp$insertion_position * super_temp$length)
all_momentum <- sum(super_temp$momentum)
all_momentum
[1] 6.590597
all_length <- sum(super_temp$length)
all_length
[1] 8.455498
CoG <- (all_momentum / all_length)
CoG
[1] 0.7794452

Finally - let’s add all these values into our MR_only table

First we need to create needed columns:

only_MR$Apical <- 0
only_MR$Branched <- 0
only_MR$Basal <- 0

only_MR$Apical_perc <- 0
only_MR$Branched_perc <- 0
only_MR$Basal_perc <- 0
only_MR$LR_no_10_100 <- 0
only_MR$LR_no_20_100 <- 0
only_MR$LR_no_30_100 <- 0
only_MR$LR_no_40_100 <- 0
only_MR$LR_no_50_100 <- 0
only_MR$LR_no_60_100 <- 0
only_MR$LR_no_70_100 <- 0
only_MR$LR_no_80_100 <- 0
only_MR$LR_no_90_100 <- 0
only_MR$LR_no_100_100 <- 0

only_MR$LRL_10_100 <- 0
only_MR$LRL_20_100 <- 0
only_MR$LRL_30_100 <- 0
only_MR$LRL_40_100 <- 0
only_MR$LRL_50_100 <- 0
only_MR$LRL_60_100 <- 0
only_MR$LRL_70_100 <- 0
only_MR$LRL_80_100 <- 0
only_MR$LRL_90_100 <- 0
only_MR$LRL_100_100 <- 0

only_MR$CoG <- 0
only_MR$LRL.dec <- 0
only_MR$LRL.dec.R2 <- 0
head(only_MR)

then add values to these columns:

only_MR$Apical[1] <- Apical
only_MR$Branched[1] <- Branched
only_MR$Basal[1] <- Basal

only_MR$Apical_perc[1] <- (Apical / MR_length)
only_MR$Branched_perc[1] <- (Branched / MR_length)
only_MR$Basal_perc[1] <- (Basal / MR_length)
only_MR$LR_no_10_100[1] <- LR_no_10_100
only_MR$LR_no_20_100[1] <- LR_no_20_100
only_MR$LR_no_30_100[1] <- LR_no_30_100
only_MR$LR_no_40_100[1] <- LR_no_40_100
only_MR$LR_no_50_100[1] <- LR_no_50_100
only_MR$LR_no_60_100[1] <- LR_no_60_100
only_MR$LR_no_70_100[1] <- LR_no_70_100
only_MR$LR_no_80_100[1] <- LR_no_80_100
only_MR$LR_no_90_100[1] <- LR_no_90_100
only_MR$LR_no_100_100[1] <- LR_no_100_100

only_MR$LRL_10_100[1] <- LRL_10_100
only_MR$LRL_20_100[1] <- LRL_20_100
only_MR$LRL_30_100[1] <- LRL_30_100
only_MR$LRL_40_100[1] <- LRL_40_100
only_MR$LRL_50_100[1] <- LRL_50_100
only_MR$LRL_60_100[1] <- LRL_60_100
only_MR$LRL_70_100[1] <- LRL_70_100
only_MR$LRL_80_100[1] <- LRL_80_100
only_MR$LRL_90_100[1] <- LRL_90_100
only_MR$LRL_100_100[1] <- LRL_100_100

only_MR$CoG[1] <- CoG

only_MR$LRL.dec[1] <- LRL.dec
only_MR$LRL.dec.R2[1] <- LRL.dec.R2  

head(only_MR)

cool - looks good. Let’s loop it:

dim(final)
[1] 41269    15
length(all_img)
[1] 4460
for(i in c(2:4460)){
  MR_now <- all_img[i]
  super_temp <- subset(final, final$image %in% MR_now)
  MR_length <- subset(only_MR, only_MR$image %in% MR_now)
  MR_length <- MR_length$MRL
  super_temp <- subset(super_temp, super_temp$root_ontology == unique(super_temp$root_ontology)[2])
  Apical <- min(super_temp$insertion_position)
  Branched <- (max(super_temp$insertion_position) - Apical)
  Basal <- MR_length - max(super_temp$insertion_position)
  
  super_temp$LR_in_10_perc <- 0
  super_temp$LR_in_20_perc <- 0
  super_temp$LR_in_30_perc <- 0
  super_temp$LR_in_40_perc <- 0
  super_temp$LR_in_50_perc <- 0
  super_temp$LR_in_60_perc <- 0
  super_temp$LR_in_70_perc <- 0
  super_temp$LR_in_80_perc <- 0
  super_temp$LR_in_90_perc <- 0
  super_temp$LR_in_100_perc <- 0

  for(e in 1:nrow(super_temp)){
     if (super_temp$insertion_position[e] < (MR_length/10)){
      super_temp$LR_in_10_perc[e] <- 1
     } else {super_temp$LR_in_10_perc[e] <- 0}
    if (super_temp$insertion_position[e] < 2*(MR_length/10) & super_temp$insertion_position[e] > (MR_length/10)){
      super_temp$LR_in_20_perc[e] <- 1
    } else {super_temp$LR_in_20_perc[e] <- 0}
    if (super_temp$insertion_position[e] < 3*(MR_length/10) & super_temp$insertion_position[e] > 2*(MR_length/10)){
      super_temp$LR_in_30_perc[e] <- 1
    } else {super_temp$LR_in_30_perc[e] <- 0}
    if (super_temp$insertion_position[e] < 4*(MR_length/10) & super_temp$insertion_position[e] > 3*(MR_length/10)){
      super_temp$LR_in_40_perc[e] <- 1
    } else {super_temp$LR_in_40_perc[e] <- 0}
    if (super_temp$insertion_position[e] < 5*(MR_length/10) & super_temp$insertion_position[e] > 4*(MR_length/10)){
      super_temp$LR_in_50_perc[e] <- 1
    } else {super_temp$LR_in_50_perc[e] <- 0}
    if (super_temp$insertion_position[e] < 6*(MR_length/10) & super_temp$insertion_position[e] > 5*(MR_length/10)){
      super_temp$LR_in_60_perc[e] <- 1
    } else {super_temp$LR_in_60_perc[e] <- 0}
    if (super_temp$insertion_position[e] < 7*(MR_length/10) & super_temp$insertion_position[e] > 6*(MR_length/10)){
      super_temp$LR_in_70_perc[e] <- 1
    } else {super_temp$LR_in_70_perc[e] <- 0}
    if (super_temp$insertion_position[e] < 8*(MR_length/10) & super_temp$insertion_position[e] > 7*(MR_length/10)){
      super_temp$LR_in_80_perc[e] <- 1
    } else {super_temp$LR_in_80_perc[e] <- 0}
    if (super_temp$insertion_position[e] < 9*(MR_length/10) & super_temp$insertion_position[e] > 8*(MR_length/10)){
      super_temp$LR_in_90_perc[e] <- 1
    } else {super_temp$LR_in_90_perc[e] <- 0}
    if (super_temp$insertion_position[e] < 10*(MR_length/10) & super_temp$insertion_position[e] > 9*(MR_length/10)){
      super_temp$LR_in_100_perc[e] <- 1
    } else {super_temp$LR_in_100_perc[e] <- 0}
  } 

  super_temp$LRL_in_10_perc <- super_temp$length * super_temp$LR_in_10_perc
  super_temp$LRL_in_20_perc <- super_temp$length * super_temp$LR_in_20_perc
  super_temp$LRL_in_30_perc <- super_temp$length * super_temp$LR_in_30_perc
  super_temp$LRL_in_40_perc <- super_temp$length * super_temp$LR_in_40_perc
  super_temp$LRL_in_50_perc <- super_temp$length * super_temp$LR_in_50_perc
  super_temp$LRL_in_60_perc <- super_temp$length * super_temp$LR_in_60_perc
  super_temp$LRL_in_70_perc <- super_temp$length * super_temp$LR_in_70_perc
  super_temp$LRL_in_80_perc <- super_temp$length * super_temp$LR_in_80_perc
  super_temp$LRL_in_90_perc <- super_temp$length * super_temp$LR_in_90_perc
  super_temp$LRL_in_100_perc <- super_temp$length * super_temp$LR_in_100_perc
  
  LR_no_10_100 <- sum(super_temp$LR_in_10_perc)
  LR_no_20_100 <- sum(super_temp$LR_in_20_perc)
  LR_no_30_100 <- sum(super_temp$LR_in_30_perc)
  LR_no_40_100 <- sum(super_temp$LR_in_40_perc)
  LR_no_50_100 <- sum(super_temp$LR_in_50_perc)
  LR_no_60_100 <- sum(super_temp$LR_in_60_perc)
  LR_no_70_100 <- sum(super_temp$LR_in_70_perc)
  LR_no_80_100 <- sum(super_temp$LR_in_80_perc)
  LR_no_90_100 <- sum(super_temp$LR_in_90_perc)
  LR_no_100_100 <- sum(super_temp$LR_in_100_perc)
  
  LRL_10_100 <- sum(super_temp$LRL_in_10_perc)
  LRL_20_100 <- sum(super_temp$LRL_in_20_perc)
  LRL_30_100 <- sum(super_temp$LRL_in_30_perc)
  LRL_40_100 <- sum(super_temp$LRL_in_40_perc)
  LRL_50_100 <- sum(super_temp$LRL_in_50_perc)
  LRL_60_100 <- sum(super_temp$LRL_in_60_perc)
  LRL_70_100 <- sum(super_temp$LRL_in_70_perc)
  LRL_80_100 <- sum(super_temp$LRL_in_80_perc)
  LRL_90_100 <- sum(super_temp$LRL_in_90_perc)
  LRL_100_100 <- sum(super_temp$LRL_in_100_perc)
  
  super_temp$momentum <- (super_temp$insertion_position * super_temp$length)
  all_momentum <- sum(super_temp$momentum)
  all_length <- sum(super_temp$length)
  CoG <- (all_momentum / all_length)  
  
  if(dim(super_temp)[1] > 2){
  model <- lm(super_temp$length ~ super_temp$insertion_position)
  LRL.dec <- model$coefficients[[2]]
  LRL.dec.R2 <- summary(model)$r.squared
  } else {
    LRL.dec <- "n.a."
    LRL.dec.R2 <- "n.a."
  }
  
  
  only_MR$Apical[i] <- Apical
  only_MR$Branched[i] <- Branched
  only_MR$Basal[i] <- Basal
  
  only_MR$Apical_perc[i] <- (Apical / MR_length)
  only_MR$Branched_perc[i] <- (Branched / MR_length)
  only_MR$Basal_perc[i] <- (Basal / MR_length)
  only_MR$LR_no_10_100[i] <- LR_no_10_100
  only_MR$LR_no_20_100[i] <- LR_no_20_100
  only_MR$LR_no_30_100[i] <- LR_no_30_100
  only_MR$LR_no_40_100[i] <- LR_no_40_100
  only_MR$LR_no_50_100[i] <- LR_no_50_100
  only_MR$LR_no_60_100[i] <- LR_no_60_100
  only_MR$LR_no_70_100[i] <- LR_no_70_100
  only_MR$LR_no_80_100[i] <- LR_no_80_100
  only_MR$LR_no_90_100[i] <- LR_no_90_100
  only_MR$LR_no_100_100[i] <- LR_no_100_100
  
  only_MR$LRL_10_100[i] <- LRL_10_100
  only_MR$LRL_20_100[i] <- LRL_20_100
  only_MR$LRL_30_100[i] <- LRL_30_100
  only_MR$LRL_40_100[i] <- LRL_40_100
  only_MR$LRL_50_100[i] <- LRL_50_100
  only_MR$LRL_60_100[i] <- LRL_60_100
  only_MR$LRL_70_100[i] <- LRL_70_100
  only_MR$LRL_80_100[i] <- LRL_80_100
  only_MR$LRL_90_100[i] <- LRL_90_100
  only_MR$LRL_100_100[i] <- LRL_100_100
  
  only_MR$CoG[i] <- CoG
  only_MR$LRL.dec[i] <- LRL.dec
  only_MR$LRL.dec.R2[i] <- LRL.dec.R2  
}

let’s have a look at the entire table:

head(only_MR)
tail(only_MR)

then- we need to fuse all the main roots that dont own LR

Make sure that the data structure is the same as for the only_MR file

head(no_LR_MR)

let’s add missing collumns:

no_LR_MR$Apical <- "n.a."
no_LR_MR$Branched <- "n.a."
no_LR_MR$Basal <- "n.a."

no_LR_MR$Apical_perc <- "n.a."
no_LR_MR$Branched_perc <- "n.a."
no_LR_MR$Basal_perc <- "n.a."

no_LR_MR$LR_no_10_100 <- 0
no_LR_MR$LR_no_20_100 <- 0
no_LR_MR$LR_no_30_100 <- 0
no_LR_MR$LR_no_40_100 <- 0
no_LR_MR$LR_no_50_100 <- 0
no_LR_MR$LR_no_60_100 <- 0
no_LR_MR$LR_no_70_100 <- 0
no_LR_MR$LR_no_80_100 <- 0
no_LR_MR$LR_no_90_100 <- 0
no_LR_MR$LR_no_100_100 <- 0

no_LR_MR$LRL_10_100 <- 0
no_LR_MR$LRL_20_100 <- 0
no_LR_MR$LRL_30_100 <- 0
no_LR_MR$LRL_40_100 <- 0
no_LR_MR$LRL_50_100 <- 0
no_LR_MR$LRL_60_100 <- 0
no_LR_MR$LRL_70_100 <- 0
no_LR_MR$LRL_80_100 <- 0
no_LR_MR$LRL_90_100 <- 0
no_LR_MR$LRL_100_100 <- 0

no_LR_MR$CoG <- 0
no_LR_MR$LRL.dec <- "n.a."
no_LR_MR$LRL.dec.R2 <- "n.a."

finally - let’s fuse the two files together:

colnames(only_MR)
 [1] "image"                 "root_name"             "root"                  "experiment"           
 [5] "date"                  "genotype"              "rep"                   "cond"                 
 [9] "MRL"                   "n_child"               "insertion_first_child" "insertion_last_child" 
[13] "image_id"              "Apical"                "Branched"              "Basal"                
[17] "Apical_perc"           "Branched_perc"         "Basal_perc"            "LR_no_10_100"         
[21] "LR_no_20_100"          "LR_no_30_100"          "LR_no_40_100"          "LR_no_50_100"         
[25] "LR_no_60_100"          "LR_no_70_100"          "LR_no_80_100"          "LR_no_90_100"         
[29] "LR_no_100_100"         "LRL_10_100"            "LRL_20_100"            "LRL_30_100"           
[33] "LRL_40_100"            "LRL_50_100"            "LRL_60_100"            "LRL_70_100"           
[37] "LRL_80_100"            "LRL_90_100"            "LRL_100_100"           "CoG"                  
[41] "LRL.dec"               "LRL.dec.R2"           
colnames(no_LR_MR)
 [1] "image"                 "root_name"             "root"                  "experiment"           
 [5] "date"                  "genotype"              "rep"                   "cond"                 
 [9] "MRL"                   "n_child"               "insertion_first_child" "insertion_last_child" 
[13] "Apical"                "Branched"              "Basal"                 "Apical_perc"          
[17] "Branched_perc"         "Basal_perc"            "LR_no_10_100"          "LR_no_20_100"         
[21] "LR_no_30_100"          "LR_no_40_100"          "LR_no_50_100"          "LR_no_60_100"         
[25] "LR_no_70_100"          "LR_no_80_100"          "LR_no_90_100"          "LR_no_100_100"        
[29] "LRL_10_100"            "LRL_20_100"            "LRL_30_100"            "LRL_40_100"           
[33] "LRL_50_100"            "LRL_60_100"            "LRL_70_100"            "LRL_80_100"           
[37] "LRL_90_100"            "LRL_100_100"           "CoG"                   "LRL.dec"              
[41] "LRL.dec.R2"           
only_MR <- only_MR[,c(1:12,14:42)]
all_MR <- rbind(only_MR, no_LR_MR)
head(all_MR)
dim(all_MR)
[1] 5511   41
length(unique(all_MR$root_name))
[1] 1076
length(unique(all_MR$image))
[1] 5511
length(unique(all_MR$image))/length(unique(all_MR$root_name))
[1] 5.121747

Let’s add some more interesting columns:

all_MR$LRL <- (all_MR$LRL_10_100 + all_MR$LRL_20_100 + all_MR$LRL_30_100 + all_MR$LRL_40_100 + all_MR$LRL_50_100 + all_MR$LRL_60_100 + all_MR$LRL_70_100 + all_MR$LRL_80_100 + all_MR$LRL_90_100 + all_MR$LRL_100_100)
all_MR$LRno <- (all_MR$LR_no_10_100 + all_MR$LR_no_20_100 + all_MR$LR_no_30_100 + all_MR$LR_no_40_100 + all_MR$LR_no_50_100 + all_MR$LR_no_60_100 + all_MR$LR_no_70_100 + all_MR$LR_no_80_100 + all_MR$LR_no_90_100 + all_MR$LR_no_100_100)
all_MR$aLRL <- all_MR$LRL / all_MR$LRno
all_MR$TRS <- all_MR$MRL + all_MR$LRL
head(all_MR)

data visualization

OK - now we have all the traits calculated - but we are still missing the DAY information - as in DAY after stress. So let’s calculate it per experiment:

head(all_MR)
unique(all_MR[,c("experiment", "date")])

based on the above - we have the following

day Big01 Big02 Big03 Big04 day 0 - 20190909 20190923 20190930 20191008 day 1 - 20190910 20190924 20191001 20191009 day 2 - 20190911 20190925 20191002 20191010 day 3 - 20190912 20190926 20191003 20191011 day 4 - 20190913 20190927 20191004 20191012

So now we have to do conditional formating for DAS (Days After Stress):

all_MR$DAS <- all_MR$date
all_MR$DAS <- gsub("20190909", "0", all_MR$DAS)
all_MR$DAS <- gsub("20190923", "0", all_MR$DAS)
all_MR$DAS <- gsub("20190930", "0", all_MR$DAS)
all_MR$DAS <- gsub("20191008", "0", all_MR$DAS)

all_MR$DAS <- gsub("20190910", "1", all_MR$DAS)
all_MR$DAS <- gsub("20190924", "1", all_MR$DAS)
all_MR$DAS <- gsub("20191001", "1", all_MR$DAS)
all_MR$DAS <- gsub("20191009", "1", all_MR$DAS)

all_MR$DAS <- gsub("20190911", "2", all_MR$DAS)
all_MR$DAS <- gsub("20190925", "2", all_MR$DAS)
all_MR$DAS <- gsub("20191002", "2", all_MR$DAS)
all_MR$DAS <- gsub("20191010", "2", all_MR$DAS)

all_MR$DAS <- gsub("20190912", "3", all_MR$DAS)
all_MR$DAS <- gsub("20190926", "3", all_MR$DAS)
all_MR$DAS <- gsub("20191003", "3", all_MR$DAS)
all_MR$DAS <- gsub("20191011", "3", all_MR$DAS)

all_MR$DAS <- gsub("20190913", "4", all_MR$DAS)
all_MR$DAS <- gsub("20190927", "4", all_MR$DAS)
all_MR$DAS <- gsub("20191004", "4", all_MR$DAS)
all_MR$DAS <- gsub("20191012", "4", all_MR$DAS)

unique(all_MR[,c("experiment", "DAS")])

before we go any further - let’s clean up this data and add whatever else missing traits:

colnames(all_MR)
 [1] "image"                 "root_name"             "root"                  "experiment"           
 [5] "date"                  "genotype"              "rep"                   "cond"                 
 [9] "MRL"                   "n_child"               "insertion_first_child" "insertion_last_child" 
[13] "Apical"                "Branched"              "Basal"                 "Apical_perc"          
[17] "Branched_perc"         "Basal_perc"            "LR_no_10_100"          "LR_no_20_100"         
[21] "LR_no_30_100"          "LR_no_40_100"          "LR_no_50_100"          "LR_no_60_100"         
[25] "LR_no_70_100"          "LR_no_80_100"          "LR_no_90_100"          "LR_no_100_100"        
[29] "LRL_10_100"            "LRL_20_100"            "LRL_30_100"            "LRL_40_100"           
[33] "LRL_50_100"            "LRL_60_100"            "LRL_70_100"            "LRL_80_100"           
[37] "LRL_90_100"            "LRL_100_100"           "CoG"                   "LRL.dec"              
[41] "LRL.dec.R2"            "LRL"                   "LRno"                  "aLRL"                 
[45] "TRS"                   "DAS"                  
dim(all_MR)
[1] 5511   46
all_MR2 <- all_MR[,c(1:4, 46, 6:9, 13:45)]
head(all_MR2)
all_MR2$MRL.p.TRS <- all_MR2$MRL / all_MR2$TRS
all_MR2$aLRL.p.TRS <- all_MR2$aLRL / all_MR2$TRS
all_MR2$LRL_10_perc <- all_MR2$LRL_10_100 / all_MR2$LRL
all_MR2$LRL_20_perc <- all_MR2$LRL_20_100 / all_MR2$LRL
all_MR2$LRL_30_perc <- all_MR2$LRL_30_100 / all_MR2$LRL
all_MR2$LRL_40_perc <- all_MR2$LRL_40_100 / all_MR2$LRL
all_MR2$LRL_50_perc <- all_MR2$LRL_50_100 / all_MR2$LRL
all_MR2$LRL_60_perc <- all_MR2$LRL_60_100 / all_MR2$LRL
all_MR2$LRL_70_perc <- all_MR2$LRL_70_100 / all_MR2$LRL
all_MR2$LRL_80_perc <- all_MR2$LRL_80_100 / all_MR2$LRL
all_MR2$LRL_90_perc <- all_MR2$LRL_90_100 / all_MR2$LRL
all_MR2$LRL_100_perc <- all_MR2$LRL_100_100 / all_MR2$LRL

all_MR2$LRno_10_perc <- all_MR2$LR_no_10_100 / all_MR2$LRno
all_MR2$LRno_20_perc <- all_MR2$LR_no_20_100 / all_MR2$LRno
all_MR2$LRno_30_perc <- all_MR2$LR_no_30_100 / all_MR2$LRno
all_MR2$LRno_40_perc <- all_MR2$LR_no_40_100 / all_MR2$LRno
all_MR2$LRno_50_perc <- all_MR2$LR_no_50_100 / all_MR2$LRno
all_MR2$LRno_60_perc <- all_MR2$LR_no_60_100 / all_MR2$LRno
all_MR2$LRno_70_perc <- all_MR2$LR_no_70_100 / all_MR2$LRno
all_MR2$LRno_80_perc <- all_MR2$LR_no_80_100 / all_MR2$LRno
all_MR2$LRno_90_perc <- all_MR2$LR_no_90_100 / all_MR2$LRno
all_MR2$LRno_100_perc <- all_MR2$LR_no_100_100 / all_MR2$LRno

head(all_MR2)

Just before we start plotting the data - let’s also check the genotype information whether this all makes sense and if we are not missing any info:

unique(all_MR2$genotype)
  [1] " 189"  " 292"  " 213"  " 212"  " 307"  " 282"  " 298"  " 301"  " 286"  " 214"  " 194"  " 294"  " 285"  " 293" 
 [15] " 284"  " 278"  " 300"  " 201"  " 279"  " 280"  " 299"  " 200"  " 211"  " 308"  " 197"  " 287"  " 196"  " 220" 
 [29] " 207"  " 290"  " 198"  " 195"  " 289"  " 288"  " 291"  " 2800" " 199"  " 277"  " 283"  " 306"  " 235"  " 192" 
 [43] " 147"  " 252"  " 166"  " 269"  " 064"  " 253"  " 193"  " 146"  " 141"  " 251"  " 139"  " 169"  " 258"  " 144" 
 [57] " 138"  " 061"  " 065"  " 170"  " 142"  " 140"  " 168"  " 272"  " 165"  " 255"  " 260"  " 264"  " 262"  " 261" 
 [71] " 167"  " 060"  " 066"  " 136"  " 256"  " 143"  " 171"  " 082"  " 083"  " 191"  " 259"  " 062"  " 172"  " 063" 
 [85] " 270"  " 268"  " 267"  " 234"  " 245"  " 173"  " 236"  " 084"  " 229"  " 241"  " 231"  " 227"  " 176"  " 087" 
 [99] " 091"  " 090"  " 085"  " 228"  " 230"  " 175"  " 250"  " 222"  " 239"  " 233"  " 274"  " 088"  " 271"  " 240" 
[113] " 092"  " 089"  " 247"  " 038"  " 248"  " 086"  " 273"  " 244"  " 093"  " 174"  " 249"  " 237"  " 221"  " 225" 
[127] " 103"  " 028"  " 098"  " 055"  " 075"  " 059"  " 101"  " 034"  " 002"  " 030"  " 056"  " 001"  " 102"  " 012" 
[141] " 076"  " 079"  " 104"  " 081"  " 096"  " 058"  " 099"  " 105"  " 040"  " 035"  " 094"  " 074"  " 032"  " 022" 
[155] " 003"  " 095"  " 009"  " 106"  " 057"  " 033"  " 029"  " 013"  " 031"  " 007"  " 008"  " 006"  " 080"  " 005" 
[169] " 036"  " 011"  " 078"  " 010"  " 097"  " 037" 
unique(all_MR$root_name)
   [1] " 189_3_C"  " 292_3_S"  " 213_3_S"  " 212_1_S"  " 307_2_C"  " 282_3_C"  " 298_3_S"  " 301_1_C"  " 286_1_S" 
  [10] " 213_2_C"  " 214_1_C"  " 286_2_C"  " 194_1_S"  " 212_1_C"  " 294_2_C"  " 213_1_C"  " 285_2_S"  " 293_2_C" 
  [19] " 284_2_S"  " 285_3_S"  " 278_1_C"  " 300_1_S"  " 214_3_C"  " 292_1_C"  " 201_2_S"  " 279_1_S"  " 293_3_S" 
  [28] " 280_1_S"  " 194_3_S"  " 294_3_S"  " 299_2_C"  " 298_3_C"  " 282_1_C"  " 285_3_C"  " 307_3_C"  " 200_1_S" 
  [37] " 211_3_S"  " 308_3_C"  " 308_2_C"  " 197_3_S"  " 287_1_C"  " 301_1_S"  " 196_1_C"  " 299_1_C"  " 220_3_C" 
  [46] " 293_2_S"  " 207_1_C"  " 280_1_C"  " 220_1_C"  " 213_2_S"  " 194_3_C"  " 194_1_C"  " 282_2_S"  " 290_3_C" 
  [55] " 196_2_C"  " 300_2_C"  " 198_2_C"  " 211_1_C"  " 285_2_C"  " 197_1_C"  " 292_2_C"  " 195_2_S"  " 294_2_S" 
  [64] " 289_2_S"  " 282_2_C"  " 299_1_S"  " 300_3_C"  " 197_2_C"  " 298_2_C"  " 288_3_C"  " 213_3_C"  " 201_3_C" 
  [73] " 291_3_C"  " 2800_3_S" " 196_1_S"  " 279_1_C"  " 278_3_S"  " 213_1_S"  " 294_1_C"  " 294_1_S"  " 195_1_C" 
  [82] " 199_3_C"  " 290_1_C"  " 197_3_C"  " 212_2_S"  " 211_2_S"  " 211_2_C"  " 199_1_C"  " 214_1_S"  " 277_1_S" 
  [91] " 197_1_S"  " 292_3_C"  " 291_2_C"  " 207_2_C"  " 214_2_C"  " 285_1_S"  " 194_2_C"  " 278_2_C"  " 291_1_C" 
 [100] " 212_3_S"  " 300_3_S"  " 284_1_C"  " 293_1_S"  " 283_1_C"  " 211_3_C"  " 283_3_S"  " 286_3_C"  " 277_2_C" 
 [109] " 279_3_S"  " 283_1_S"  " 298_1_S"  " 211_1_S"  " 197_2_S"  " 288_1_S"  " 300_2_S"  " 294_3_C"  " 198_3_S" 
 [118] " 201_1_C"  " 288_2_C"  " 207_3_S"  " 288_1_C"  " 280_3_C"  " 306_1_C"  " 212_2_C"  " 212_3_C"  " 207_3_C" 
 [127] " 286_2_S"  " 201_1_S"  " 277_1_C"  " 195_3_C"  " 283_2_C"  " 288_3_S"  " 291_2_S"  " 290_2_C"  " 298_1_C" 
 [136] " 284_1_S"  " 308_3_S"  " 284_2_C"  " 290_1_S"  " 195_3_S"  " 214_3_S"  " 200_3_S"  " 200_2_S"  " 195_2_C" 
 [145] " 200_1_C"  " 279_3_C"  " 301_2_C"  " 288_2_S"  " 301_3_S"  " 308_1_C"  " 279_2_C"  " 306_2_C"  " 286_1_C" 
 [154] " 291_1_S"  " 280_2_C"  " 199_2_C"  " 235_1_C"  " 290_2_S"  " 195_1_S"  " 283_3_C"  " 290_3_S"  " 199_3_S" 
 [163] " 293_3_C"  " 198_1_S"  " 198_2_S"  " 292_2_S"  " 198_1_C"  " 200_2_C"  " 286_3_S"  " 200_3_C"  " 201_2_C" 
 [172] " 293_4_C"  " 308_2_S"  " 291_3_S"  " 282_3_S"  " 201_3_S"  " 278_3_C"  " 283_2_S"  " 287_3_C"  " 278_2_S" 
 [181] " 282_1_S"  " 199_2_S"  " 278_1_S"  " 307_2_S"  " 307_1_S"  " 299_3_C"  " 199_1_S"  " 307_3_S"  " 220_2_C" 
 [190] " 287_2_S"  " 301_3"    " 287_2_C"  " 307_1_C"  " 220_1_S"  " 306_3_C"  " 299_2_S"  " 308_1_S"  " 277_2_S" 
 [199] " 192_3_C"  " 207_1_S"  " 301_2_S"  " 194_2_S"  " 214_2_S"  " 306_1_S"  " 207_2_S"  " 306_3_S"  " 287_3_S" 
 [208] " 147_3_C"  " 252_1_S"  " 166_1_C"  " 269_3_C"  " 064_1_C"  " 253_2_S"  " 193_1_S"  " 146_3_C"  " 141_2_C" 
 [217] " 251_3_S"  " 139_3_S"  " 169_1_S"  " 258_3_S"  " 192_1_C"  " 144_2_C"  " 147_2_C"  " 253_3_S"  " 138_3_S" 
 [226] " 146_2_C"  " 193_1_C"  " 061_2_C"  " 065_3_S"  " 170_3_C"  " 141_1_C"  " 144_1_C"  " 142_4_S"  " 139_1_S" 
 [235] " 140_3_C"  " 168_3_S"  " 272_2_C"  " 138_4_C"  " 147_1_S"  " 269_3_S"  " 165_1_S"  " 144_2_S"  " 255_1_S" 
 [244] " 138_1_C"  " 272_3_S"  " 138_4_S"  " 251_2_C"  " 269_1_C"  " 260_2_C"  " 264_2_S"  " 262_3_C"  " 261_1_S" 
 [253] " 192_3_S"  " 065_2_S"  " 168_3_C"  " 260_1_C"  " 167_1_S"  " 166_3_C"  " 253_2_C"  " 142_3_C"  " 060_3_S" 
 [262] " 165_2_C"  " 262_2_C"  " 066_2_C"  " 136_3_C"  " 142_3_S"  " 140_2_S"  " 256_2_S"  " 139_2_C"  " 143_2_C" 
 [271] " 262_1_C"  " 251_3_C"  " 138_2_C"  " 165_1_C"  " 139_2_S"  " 166_1_S"  " 171_3_S"  " 256_1_C"  " 146_1_C" 
 [280] " 264_1_C"  " 136_2_C"  " 065_3_C"  " 170_2_C"  " 146_2_S"  " 192_2_C"  " 255_2_C"  " 147_1_C"  " 140_2_C" 
 [289] " 169_2_C"  " 146_3_S"  " 169_3_S"  " 061_1_C"  " 061_3_C"  " 262_4_C"  " 252_2_S"  " 141_3_C"  " 140_3_S" 
 [298] " 166_3_S"  " 082_3_C"  " 136_1_C"  " 252_3_C"  " 083_3_C"  " 165_3_C"  " 272_3_C"  " 193_3_C"  " 141_2_S" 
 [307] " 140_1_C"  " 142_2_C"  " 191_2_C"  " 171_2_C"  " 144_3_C"  " 193_2_S"  " 144_1_S"  " 272_1_C"  " 259_3_C" 
 [316] " 138_1_S"  " 062_1_C"  " 147_2_S"  " 170_2_S"  " 172_1_C"  " 136_2_S"  " 170_1_C"  " 260_3_C"  " 063_1_S" 
 [325] " 060_2_S"  " 142_4_C"  " 256_3_C"  " 256_2_C"  " 269_2_S"  " 065_1_C"  " 138_2_S"  " 171_2_S"  " 142_1_S" 
 [334] " 193_2_C"  " 253_1_C"  " 253_1_S"  " 259_2_S"  " 065_2_C"  " 169_2_S"  " 168_2_C"  " 142_2_S"  " 171_1_C" 
 [343] " 060_3_C"  " 192_1_S"  " 171_1_S"  " 261_2_C"  " 169_1_C"  " 191_1_C"  " 258_2_C"  " 063_1_C"  " 258_3_C" 
 [352] " 261_3_C"  " 270_2_C"  " 140_1_S"  " 252_1_C"  " 083_2_C"  " 264_3_C"  " 082_2_C"  " 258_1_C"  " 169_3_C" 
 [361] " 272_2_S"  " 168_1_C"  " 255_1_C"  " 256_3_S"  " 138_3_C"  " 139_3_C"  " 061_3_S"  " 136_3_S"  " 082_1_C" 
 [370] " 262_4_S"  " 253_3_C"  " 191_3_C"  " 272_1_S"  " 268_2_C"  " 192_2_S"  " 144_3_S"  " 259_1_C"  " 172_2_C" 
 [379] " 136_1_S"  " 147_3_S"  " 142_1_C"  " 060_1_C"  " 083_1_C"  " 267_2_C"  " 066_1_C"  " 252_3_S"  " 146_1_S" 
 [388] " 264_2_C"  " 268_3_C"  " 262_1_S"  " 251_1_C"  " 165_3_S"  " 268_3_S"  " 269_1_S"  " 269_2_C"  " 171_3_C" 
 [397] " 165_2_S"  " 166_2_C"  " 260_1_S"  " 060_2_C"  " 139_1_C"  " 172_3_C"  " 270_1_C"  " 060_1_S"  " 260_2_S" 
 [406] " 261_1_C"  " 264_1_S"  " 261_2_S"  " 260_3_S"  " 172_1_S"  " 191_1_S"  " 251_2_S"  " 255_2_S"  " 258_1_S" 
 [415] " 267_1_C"  " 065_1_S"  " 141_1_S"  " 143_1_C"  " 268_2_S"  " 062_2_S"  " 256_1_S"  " 262_3_S"  " 261_3_S" 
 [424] " 259_2_C"  " 270_2_S"  " 191_3_S"  " 141_3_S"  " 061_2_S"  " 066_1_S"  " 252_2_C"  " 168_2_S"  " 082_3_S" 
 [433] " 264_3_S"  " 259_3_S"  " 143_1_S"  " 193_3_S"  " 167_1_C"  " 259_1_S"  " 191_2_S"  " 262_2_S"  " 170_3_S" 
 [442] " 267_1_S"  " 066_2_S"  " 061_1_S"  " 168_1_S"  " 172_3_S"  " 064_1_S"  " 082_2_S"  " 270_1_S"  " 166_2_S" 
 [451] " 172_2_S"  " 064_2_S"  " 251_1_S"  " 143_2_S"  " 258_2_S"  " 083_2_S"  " 083_3_S"  " 268_1_S"  " 234_1_C" 
 [460] " 245_3_S"  " 173_4_C"  " 236_3_S"  " 084_3_C"  " 229_4_C"  " 245_1_S"  " 236_4_C"  " 241_1_C"  " 231_2_S" 
 [469] " 245_4_S"  " 227_1_C"  " 176_1_C"  " 229_4_S"  " 235_2_S"  " 087_1_S"  " 091_4_S"  " 090_3_C"  " 091_4_C" 
 [478] " 085_2_S"  " 228_2_C"  " 230_3_s"  " 175_4_C"  " 250_1_C"  " 222_2_S"  " 229_2_S"  " 239_4_C"  " 229_3_S" 
 [487] " 233_1_C"  " 250_4_S"  " 274_2_C"  " 088_1_C"  " 230_1_S"  " 234_2_C"  " 271_2_S"  " 173_1_C"  " 240_2_S" 
 [496] " 092_4_C"  " 084_1_S"  " 084_1_C"  " 229_3_C"  " 233_3_S"  " 236_1_S"  " 239_4_S"  " 236_2_S"  " 173_3_C" 
 [505] " 233_2_C"  " 089_3_C"  " 234_2_S"  " 241_2_C"  " 084_3_S"  " 247_1_S"  " 245_3_C"  " 089_1_"   " 247_3_C" 
 [514] " 239_3_C"  " 038_2_S"  " 250_3_S"  " 247_2_C"  " 228_4_C"  " 248_4_C"  " 086_3_C"  " 231_2_C"  " 173_1_S" 
 [523] " 085_3_S"  " 086_1_C"  " 085_2_C"  " 228_2_S"  " 084_2_S"  " 231_3_C"  " 273_3_C"  " 175_3_C"  " 176_2_S" 
 [532] " 091_2_S"  " 271_1_C"  " 084_4_C"  " 173_4_S"  " 274_4_C"  " 239_1_S"  " 236_2_C"  " 173_2_C"  " 230_2_S" 
 [541] " 092_1_C"  " 250_4_C"  " 240_3_C"  " 176_4_C"  " 092_3_C"  " 244_3_C"  " 176_2_C"  " 240_2_C"  " 274_1_S" 
 [550] " 088_1_S"  " 240_1_S"  " 088_3_C"  " 092_2_C"  " 086_1_S"  " 089_2_C"  " 092_3_S"  " 091_3_S"  " 093_3_C" 
 [559] " 229_1_S"  " 236_3_C"  " 087_3_C"  " 092_2_S"  " 239_2_S"  " 248_2_C"  " 229_1_C"  " 250_3_C"  " 038_3_C" 
 [568] " 233_3_C"  " 230_1_C"  " 236_4_S"  " 175_2_C"  " 271_4_S"  " 228_3_C"  " 093_1_S"  " 173_2_S"  " 087_4_C" 
 [577] " 090_2_C"  " 273_1_C"  " 084_4_S"  " 239_2_C"  " 233_4_S"  " 271_2_C"  " 175_3_S"  " 092_1_S"  " 233_1_S" 
 [586] " 174_4_C"  " 038_1_C"  " 087_1_C"  " 092_4_S"  " 231_3_S"  " 176_3_C"  " 247_4_C"  " 248_4_S"  " 245_2_S" 
 [595] " 240_3_S"  " 241_3_C"  " 245_1_C"  " 085_1_C"  " 174_2_S"  " 089_4_C"  " 087_2_C"  " 273_3_S"  " 250_2_C" 
 [604] " 271_3_C"  " 273_4_C"  " 228_3_S"  " 248_2_S"  " 249_1_S"  " 228_1_C"  " 271_3_S"  " 236_1_C"  " 089_3_S" 
 [613] " 229_2_C"  " 273_4_S"  " 085_3_C"  " 175_4_S"  " 244_2_C"  " 089_4_S"  " 271_4_C"  " 087_3_S"  " 250_2_S" 
 [622] " 274_2_S"  " 174_2_C"  " 274_3_S"  " 241_3_S"  " 233_4_C"  " 245_2_C"  " 173_3_S"  " 086_2_C"  " 088_3_S" 
 [631] " 093_3_S"  " 240_1_C"  " 091_1_C"  " 093_1_C"  " 227_3_C"  " 176_3_S"  " 064_3_S"  " 237_1_C"  " 244_1_S" 
 [640] " 174_3_C"  " 274_1_C"  " 247_2_S"  " 227_2_C"  " 230_3_S"  " 239_1_C"  " 093_2_C"  " 273_2_C"  " 084_2_C" 
 [649] " 093_4_C"  " 038_1_S"  " 174_1_C"  " 241_2_S"  " 038_3_S"  " 298_2_S"  " 248_1_C"  " 274_3_C"  " 089_2_S" 
 [658] " 222_1_S"  " 274_4_S"  " 090_1_C"  " 064_3_C"  " 175_1_C"  " 230_3_C"  " 247_1_C"  " 237_2_C"  " 237_4_C" 
 [667] " 250_1_S"  " 239_3_S"  " 271_1_S"  " 087_4_S"  " 227_2_S"  " 221_2_C"  " 087_2_S"  " 086_3_S"  " 174_3_S" 
 [676] " 176_4_S"  " 228_1_S"  " 175_2_S"  " 222_2_C"  " 088_2_C"  " 086_2_S"  " 237_4_S"  " 089_1_S"  " 091_3_C" 
 [685] " 234_3_C"  " 038_2_C"  " 227_1_S"  " 174_4_S"  " 233_2_S"  " 241_1_S"  " 248_3_C"  " 222_1_C"  " 093_4_S" 
 [694] " 230_2_C"  " 240_4_C"  " 237_3_C"  " 221_1_C"  " 234_1_S"  " 244_3_S"  " 176_1_S"  " 235_1_S"  " 225_2_C" 
 [703] " 248_1_S"  " 273_2_S"  " 091_1_S"  " 244_1_C"  " 091_2_C"  " 248_3_S"  " 249_1_C"  " 247_3_S"  " 175_1_S" 
 [712] " 244_2_S"  " 090_1_S"  " 093_2_S"  " 225_1_C"  " 085_1_S"  " 249_2_C"  " 249_3_C"  " 064_2_C"  " 231_1_C" 
 [721] " 090_3_S"  " 249_2_S"  " 249_3_S"  " 240_4_S"  " 237_2_S"  " 273_1_S"  " 237_1_s"  " 174_1_S"  " 090_2_S" 
 [730] " 088_2_S"  " 221_1_S"  " 247_4_S"  " 228_4_S"  " 234_3_S"  " 227_3_S"  " 237_3_S"  " 231_1_S"  " 103_4_S" 
 [739] " 028_3_S"  " 098_1_S"  " 055_2_S"  " 075_3_C"  " 059_4_C"  " 101_1_S"  " 034_1_C"  " 002_1_C"  " 030_2_S" 
 [748] " 056_3_S"  " 001_3_C"  " 102_4_C"  " 012_3_C"  " 076_1_C"  " 098_1_C"  " 079_1_C"  " 104_3_S"  " 081_1_C" 
 [757] " 101_2_C"  " 096_1_C"  " 101_2_S"  " 058_4_C"  " 028_4_C"  " 099_2_S"  " 103_3_C"  " 079_4_C"  " 030_1_S" 
 [766] " 105_4_S"  " 040_1_C"  " 035_4_C"  " 094_3_C"  " 074_4_C"  " 032_4_S"  " 056_2_C"  " 103_1_S"  " 103_1_C" 
 [775] " 022_4_C"  " 102_2_S"  " 105_3_C"  " 081_2_S"  " 003_3_S"  " 056_2_S"  " 095_1_S"  " 009_3_S"  " 002_2_S" 
 [784] " 106_1_S"  " 098_3_C"  " 040_3_S"  " 103_2_S"  " 075_2_C"  " 001_4_S"  " 009_2_S"  " 057_1_C"  " 028_3_C" 
 [793] " 033_2_C"  " 012_1_S"  " 098_3_S"  " 094_2_C"  " 029_3_S"  " 074_3_C"  " 028_1_S"  " 013_3_C"  " 031_1_S" 
 [802] " 105_1_S"  " 094_2_S"  " 007_2_C"  " 075_3_S"  " 013_2_S"  " 007_1_C"  " 008_1_S"  " 057_1_S"  " 007_3_C" 
 [811] " 059_3_C"  " 076_3_C"  " 012_3_S"  " 008_3_C"  " 007_1_S"  " 094_3_S"  " 099_4_C"  " 057_3_C"  " 099_1_C" 
 [820] " 035_2_S"  " 029_4_S"  " 030_2_C"  " 012_2_S"  " 103_4_C"  " 105_3_S"  " 007_2_S"  " 012_4_S"  " 013_1_C" 
 [829] " 032_1_C"  " 009_2_C"  " 001_1_C"  " 057_2_S"  " 098_4_S"  " 006_3_C"  " 080_1_C"  " 079_2_S"  " 056_3_C" 
 [838] " 095_4_S"  " 040_2_C"  " 001_2_S"  " 003_3_C"  " 031_2_C"  " 074_4_S"  " 035_2_C"  " 106_2_C"  " 001_2_C" 
 [847] " 104_2_S"  " 040_4_C"  " 005_3_C"  " 059_1_C"  " 079_3_S"  " 096_2_S"  " 009_1_C"  " 032_2_C"  " 057_4_S" 
 [856] " 055_2_C"  " 030_3_C"  " 095_4_C"  " 081_3_C"  " 081_4_S"  " 103_3_S"  " 059_2_C"  " 099_3_C"  " 031_4_C" 
 [865] " 038_4_C"  " 006_2_C"  " 102_3_C"  " 057_2_C"  " 104_3_C"  " 057_4_C"  " 029_3_C"  " 036_2_C"  " 058_1_C" 
 [874] " 057_3_S"  " 030_1_C"  " 032_3_S"  " 011_1_C"  " 078_1_C"  " 035_1_S"  " 029_1_C"  " 101_3_S"  " 055_1_S" 
 [883] " 008_1_C"  " 011_3_C"  " 001_1_S"  " 055_3_C"  " 003_2_S"  " 105_4_C"  " 104_4_S"  " 031_4_S"  " 102_4_S" 
 [892] " 013_2_C"  " 074_2_S"  " 075_1_S"  " 008_3_S"  " 104_1_S"  " 011_4_C"  " 058_2_C"  " 099_4_S"  " 106_2_S" 
 [901] " 075_1_C"  " 009_1_S"  " 080_2_C"  " 099_2_C"  " 074_1_S"  " 002_1_S"  " 011_3_S"  " 105_2_C"  " 080_3_S" 
 [910] " 055_3_S"  " 028_1_C"  " 008_2_S"  " 035_3_C"  " 011_2_C"  " 094_1_C"  " 013_3_S"  " 055_1_C"  " 005_2_C" 
 [919] " 005_4_C"  " 104_2_C"  " 056_1_C"  " 101_4_S"  " 079_4_S"  " 012_2_C"  " 101_4_C"  " 031_1_C"  " 059_1_S" 
 [928] " 105_1_C"  " 008_2_C"  " 029_4_C"  " 094_1_S"  " 034_3_C"  " 081_3_S"  " 002_2_C"  " 081_4_C"  " 033_1_C" 
 [937] " 074_2_C"  " 106_1_C"  " 035_4_S"  " 035_1_C"  " 011_2_S"  " 007_3_S"  " 005_1_S"  " 001_4_C"  " 101_3_C" 
 [946] " 028_2_C"  " 101_1_C"  " 013_1_S"  " 096_2_C"  " 002_3_C"  " 038_4_S"  " 076_4_C"  " 098_2_C"  " 040_2_S" 
 [955] " 012_1_C"  " 102_2_C"  " 001_3_S"  " 002_3_S"  " 012_4_C"  " 076_2_S"  " 096_3_S"  " 032_2_S"  " 002_4_S" 
 [964] " 079_2_C"  " 098_4_C"  " 095_2_C"  " 080_4_C"  " 030_3_S"  " 040_3_C"  " 040_4_S"  " 076_1_S"  " 029_2_C" 
 [973] " 032_3_C"  " 105_2_S"  " 003_1_C"  " 096_3_C"  " 102_1_C"  " 102_1_S"  " 032_4_C"  " 076_3_S"  " 104_1_C" 
 [982] " 098_2_S"  " 102_3_S"  " 075_2_S"  " 099_3_S"  " 009_4_S"  " 081_2_C"  " 031_3_C"  " 009_3_C"  " 006_1_C" 
 [991] " 009_4_C"  " 058_3_C"  " 008_4_C"  " 078_1_S"  " 103_2_C"  " 076_2_C"  " 008_4_S"  " 095_3_C"  " 104_4_C" 
[1000] " 096_1_S" 
 [ reached getOption("max.print") -- omitted 76 entries ]
all_MR2$genotype <- gsub("2800", "280", all_MR2$genotype)
all_MR2$root_name <- gsub(" 089_1_", " 089_1_C", all_MR2$root_name)
all_MR2$root_name <- gsub(" 089_1_C_C", " 089_1_C", all_MR2$root_name)
all_MR2$root_name <- gsub(" 089_1_C_S", " 089_1_S", all_MR2$root_name)

all_MR2$root_name <- gsub("301_3", "301_3_C", all_MR2$root_name)
all_MR2$root_name <- gsub("301_3_CC", "301_3_C", all_MR2$root_name)
all_MR2$root_name <- gsub("301_3_CS", "301_3_S", all_MR2$root_name)

unique(all_MR2$cond)
[1] "C" "S" NA  "s"
all_MR2$cond <- gsub("s", "S", all_MR2$cond)
unique(all_MR2$cond)
[1] "C" "S" NA 
normal_cond <- c("C", "S")
thats_it <- subset(all_MR2, (all_MR2$cond %in% normal_cond))
whats_that <- subset(all_MR2, !(all_MR2$cond %in% normal_cond))
whats_that
whats_that$cond <- "C"

all_MR3 <- rbind(thats_it, whats_that)
unique(all_MR3$cond)
[1] "C" "S"

Histograms

Library loading

OK - now we can start plotting - finally! loading the libraries

library(ggplot2)
library(ggpubr)
package ‘ggpubr’ was built under R version 4.0.2Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
library(doBy)

Attaching package: ‘doBy’

The following object is masked from ‘package:dplyr’:

    order_by
library(cowplot)

********************************************************
Note: As of version 1.0.0, cowplot does not change the
  default ggplot2 theme anymore. To recover the previous
  behavior, execute:
  theme_set(theme_cowplot())
********************************************************


Attaching package: ‘cowplot’

The following object is masked from ‘package:ggpubr’:

    get_legend
library(RColorBrewer)
library(corrplot)
corrplot 0.84 loaded
library(ggbeeswarm)
library(RColorBrewer)
library(ggridges)
library(gapminder)
library("gplots")
package ‘gplots’ was built under R version 4.0.2
Attaching package: ‘gplots’

The following object is masked from ‘package:stats’:

    lowess
library("colorRamps")

Let’s start from a simple histogram - so we can see the treatment dependent change in TRS

TRS_histo <- gghistogram(all_MR3, x = "TRS",
            add = "mean", rug = TRUE,
            color = "cond", fill = "cond", facet.by = "DAS", 
            palette = c("#00AFBB", "#E7B800")) + xlab("Total root length (cm)")
Using `bins = 30` by default. Pick better value with the argument `bins`.
TRS_histo

OK - looks as we expect it to. Let’s have a look at other things - like LR number:

LRno_histo <- gghistogram(all_MR3, x = "LRno",
            add = "mean", rug = TRUE,
            color = "cond", fill = "cond", facet.by = "DAS",
            palette = c("#00AFBB", "#E7B800")) + xlab("number of LR / Main Root")
Using `bins = 30` by default. Pick better value with the argument `bins`.
LRno_histo

LRL_histo <- gghistogram(all_MR3, x = "LRL",
            add = "mean", rug = TRUE,
            color = "cond", fill = "cond", facet.by = "DAS",
            palette = c("#00AFBB", "#E7B800")) + xlab("Lateral Root Length (cm)")
Using `bins = 30` by default. Pick better value with the argument `bins`.
LRL_histo

MRL_histo <- gghistogram(all_MR3, x = "MRL",
            add = "mean", rug = TRUE,
            color = "cond", fill = "cond", facet.by = "DAS",
            palette = c("#00AFBB", "#E7B800")) + xlab("Main root length (cm)")
Using `bins = 30` by default. Pick better value with the argument `bins`.
MRL_histo

CoG_histo <- gghistogram(all_MR3, x = "CoG",
            add = "mean", rug = TRUE,
            color = "cond", fill = "cond", facet.by = "DAS",
            palette = c("#00AFBB", "#E7B800")) + xlab("Center of Gravity (cm of MR)")
Using `bins = 30` by default. Pick better value with the argument `bins`.
CoG_histo

all_MR3$LRL.dec <- as.numeric(all_MR3$LRL.dec)
NAs introduced by coercion
LRL.dec_histo <- gghistogram(all_MR3, x = "LRL.dec",
            add = "mean", rug = TRUE,
            color = "cond", fill = "cond", facet.by = "DAS",
            palette = c("#00AFBB", "#E7B800")) + xlab("Lateral Root Length decrease over MR (cm / cm of MR)")
Using `bins = 30` by default. Pick better value with the argument `bins`.
LRL.dec_histo

the above doesnt really make sense - let’s replace all these extreme values (< -2, > 2) with “n.a.”)

temp <- subset(all_MR3, all_MR3$LRL.dec < 2)
temp <- subset(temp, temp$LRL.dec > -2)

LRL.dec_histo <- gghistogram(temp, x = "LRL.dec",
            add = "mean", rug = TRUE,
            color = "cond", fill = "cond", facet.by = "DAS",
            palette = c("#00AFBB", "#E7B800")) + xlab("Lateral Root Length decrease over MR (cm / cm of MR)")
Using `bins = 30` by default. Pick better value with the argument `bins`.
LRL.dec_histo

all_MR3$LRL.dec.R2 <- as.numeric(all_MR3$LRL.dec.R2)
NAs introduced by coercion
LRL.dec.R2_histo <- gghistogram(all_MR3, x = "LRL.dec.R2",
                                add = "mean", rug = TRUE,
                                color = "cond", fill = "cond", facet.by = "DAS",
                                palette = c("#00AFBB", "#E7B800")) + xlab("R2 of Lateral Root Length decrease over MR")
Using `bins = 30` by default. Pick better value with the argument `bins`.
LRL.dec.R2_histo

visualization of changes in RSA across time:

Let’s try to visualize changes across the accessions throughout the time using the line graph - similar to ones in Awlia et al., 2020

First - what we need to do is to calculate the average per line and per condition:

colnames(all_MR3)
 [1] "image"         "root_name"     "root"          "experiment"    "DAS"           "genotype"      "rep"          
 [8] "cond"          "MRL"           "Apical"        "Branched"      "Basal"         "Apical_perc"   "Branched_perc"
[15] "Basal_perc"    "LR_no_10_100"  "LR_no_20_100"  "LR_no_30_100"  "LR_no_40_100"  "LR_no_50_100"  "LR_no_60_100" 
[22] "LR_no_70_100"  "LR_no_80_100"  "LR_no_90_100"  "LR_no_100_100" "LRL_10_100"    "LRL_20_100"    "LRL_30_100"   
[29] "LRL_40_100"    "LRL_50_100"    "LRL_60_100"    "LRL_70_100"    "LRL_80_100"    "LRL_90_100"    "LRL_100_100"  
[36] "CoG"           "LRL.dec"       "LRL.dec.R2"    "LRL"           "LRno"          "aLRL"          "TRS"          
[43] "MRL.p.TRS"     "aLRL.p.TRS"    "LRL_10_perc"   "LRL_20_perc"   "LRL_30_perc"   "LRL_40_perc"   "LRL_50_perc"  
[50] "LRL_60_perc"   "LRL_70_perc"   "LRL_80_perc"   "LRL_90_perc"   "LRL_100_perc"  "LRno_10_perc"  "LRno_20_perc" 
[57] "LRno_30_perc"  "LRno_40_perc"  "LRno_50_perc"  "LRno_60_perc"  "LRno_70_perc"  "LRno_80_perc"  "LRno_90_perc" 
[64] "LRno_100_perc"
library(doBy)

MR_sum <- summaryBy(data = all_MR3, MRL + LRL + LRno + aLRL + TRS + MRL.p.TRS + aLRL.p.TRS + CoG + LRL.dec ~ genotype + cond + DAS)
head(MR_sum)
MR_sum$geno_cond <- paste(MR_sum$genotype, "_", MR_sum$cond, sep="")
TRS_lgraph <- ggplot(data=MR_sum, aes(x= DAS, y=TRS.mean, group = geno_cond, color = cond)) 
TRS_lgraph <- TRS_lgraph +geom_line(alpha = 0.1) 
TRS_lgraph <- TRS_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)+ stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
TRS_lgraph <- TRS_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
TRS_lgraph <- TRS_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Average per accession")
TRS_lgraph <- TRS_lgraph + ylab("Total Root Size (cm)") + xlab("Days After Stress") + theme(legend.position='none')
TRS_lgraph

MRL_lgraph <- ggplot(data=MR_sum, aes(x= DAS, y=MRL.mean, group = geno_cond, color = cond)) 
MRL_lgraph <- MRL_lgraph +geom_line(alpha = 0.1) 
MRL_lgraph <- MRL_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3) + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
MRL_lgraph <- MRL_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
MRL_lgraph <- MRL_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Average per accession")
MRL_lgraph <- MRL_lgraph + ylab("Main Root Length (cm)") + xlab("Days After Stress") + theme(legend.position='none')
MRL_lgraph

LRL_lgraph <- ggplot(data=MR_sum, aes(x= DAS, y=LRL.mean, group = geno_cond, color = cond)) 
LRL_lgraph <- LRL_lgraph +geom_line(alpha = 0.1) 
LRL_lgraph <- LRL_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)+ stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRL_lgraph <- LRL_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRL_lgraph <- LRL_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Average per accession")
LRL_lgraph <- LRL_lgraph + ylab("Lateral Root Length (cm)") + xlab("Days After Stress") + theme(legend.position='none')
LRL_lgraph

LRno_lgraph <- ggplot(data=MR_sum, aes(x= DAS, y=LRno.mean, group = geno_cond, color = cond)) 
LRno_lgraph <- LRno_lgraph +geom_line(alpha = 0.1) 
LRno_lgraph <- LRno_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3) + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRno_lgraph <- LRno_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRno_lgraph <- LRno_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Average per accession")
LRno_lgraph <- LRno_lgraph + ylab("Lateral Root Number (per MR)") + xlab("Days After Stress") + theme(legend.position='none')
LRno_lgraph

CoG_lgraph <- ggplot(data=MR_sum, aes(x= DAS, y=CoG.mean, group = geno_cond, color = cond)) 
CoG_lgraph <- CoG_lgraph +geom_line(alpha = 0.1) 
CoG_lgraph <- CoG_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3) + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
CoG_lgraph <- CoG_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
CoG_lgraph <- CoG_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Average per accession")
CoG_lgraph <- CoG_lgraph + ylab("Center of Gravity (cm of MR)") + xlab("Days After Stress") + theme(legend.position='none')
CoG_lgraph

LRL.dec_lgraph <- ggplot(data=MR_sum, aes(x= DAS, y=LRL.dec.mean, group = geno_cond, color = cond)) 
LRL.dec_lgraph <- LRL.dec_lgraph +geom_line(alpha = 0.1) 
LRL.dec_lgraph <- LRL.dec_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3) + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRL.dec_lgraph <- LRL.dec_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRL.dec_lgraph <- LRL.dec_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Average per accession")
LRL.dec_lgraph <- LRL.dec_lgraph + ylab("decrease of LRL over MRL (cm / cm of MR)") + xlab("Days After Stress") + theme(legend.position='none')
LRL.dec_lgraph

MRL.p.TRS_lgraph <- ggplot(data=MR_sum, aes(x= DAS, y=MRL.p.TRS.mean, group = geno_cond, color = cond)) 
MRL.p.TRS_lgraph <- MRL.p.TRS_lgraph +geom_line(alpha = 0.1) 
MRL.p.TRS_lgraph <- MRL.p.TRS_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3) + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
MRL.p.TRS_lgraph <- MRL.p.TRS_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
MRL.p.TRS_lgraph <- MRL.p.TRS_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Average per accession")
MRL.p.TRS_lgraph <- MRL.p.TRS_lgraph + ylab("ratio (MRL / TRS)") + xlab("Days After Stress") + theme(legend.position='none')
MRL.p.TRS_lgraph

aLRL.p.TRS_lgraph <- ggplot(data=MR_sum, aes(x= DAS, y=aLRL.p.TRS.mean, group = geno_cond, color = cond)) 
aLRL.p.TRS_lgraph <- aLRL.p.TRS_lgraph +geom_line(alpha = 0.1) 
aLRL.p.TRS_lgraph <- aLRL.p.TRS_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)
aLRL.p.TRS_lgraph <- aLRL.p.TRS_lgraph + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
aLRL.p.TRS_lgraph <- aLRL.p.TRS_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
aLRL.p.TRS_lgraph <- aLRL.p.TRS_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Average per accession")
aLRL.p.TRS_lgraph <- aLRL.p.TRS_lgraph + ylab("ratio (aLRL / TRS)") + xlab("Days After Stress") + theme(legend.position='none')
aLRL.p.TRS_lgraph

Lets combine these into one figure:

pdf("Fig.TRS_MRL_LRL_LRno_CoG_MRLpTRS_Big01_to_Big04.pdf", height = 20, width = 15)
plot_grid(TRS_lgraph, MRL_lgraph,
          LRL_lgraph, LRno_lgraph,
          CoG_lgraph, MRL.p.TRS_lgraph, ncol=2, labels = "AUTO")
dev.off()
null device 
          1 

OK - let’s keep going with exploring other cool traits…

Vizualization of LRL/LRno distribution across the root:

In order to examine how the LR is distributed across MR - lets extract all the LR distribution traits

colnames(all_MR3)
 [1] "image"         "root_name"     "root"          "experiment"    "DAS"           "genotype"      "rep"          
 [8] "cond"          "MRL"           "Apical"        "Branched"      "Basal"         "Apical_perc"   "Branched_perc"
[15] "Basal_perc"    "LR_no_10_100"  "LR_no_20_100"  "LR_no_30_100"  "LR_no_40_100"  "LR_no_50_100"  "LR_no_60_100" 
[22] "LR_no_70_100"  "LR_no_80_100"  "LR_no_90_100"  "LR_no_100_100" "LRL_10_100"    "LRL_20_100"    "LRL_30_100"   
[29] "LRL_40_100"    "LRL_50_100"    "LRL_60_100"    "LRL_70_100"    "LRL_80_100"    "LRL_90_100"    "LRL_100_100"  
[36] "CoG"           "LRL.dec"       "LRL.dec.R2"    "LRL"           "LRno"          "aLRL"          "TRS"          
[43] "MRL.p.TRS"     "aLRL.p.TRS"    "LRL_10_perc"   "LRL_20_perc"   "LRL_30_perc"   "LRL_40_perc"   "LRL_50_perc"  
[50] "LRL_60_perc"   "LRL_70_perc"   "LRL_80_perc"   "LRL_90_perc"   "LRL_100_perc"  "LRno_10_perc"  "LRno_20_perc" 
[57] "LRno_30_perc"  "LRno_40_perc"  "LRno_50_perc"  "LRno_60_perc"  "LRno_70_perc"  "LRno_80_perc"  "LRno_90_perc" 
[64] "LRno_100_perc"
dim(all_MR3)
[1] 5511   64
LR_distribution <- all_MR3[,c(1:8, 16:64)]
colnames(LR_distribution)
 [1] "image"         "root_name"     "root"          "experiment"    "DAS"           "genotype"      "rep"          
 [8] "cond"          "LR_no_10_100"  "LR_no_20_100"  "LR_no_30_100"  "LR_no_40_100"  "LR_no_50_100"  "LR_no_60_100" 
[15] "LR_no_70_100"  "LR_no_80_100"  "LR_no_90_100"  "LR_no_100_100" "LRL_10_100"    "LRL_20_100"    "LRL_30_100"   
[22] "LRL_40_100"    "LRL_50_100"    "LRL_60_100"    "LRL_70_100"    "LRL_80_100"    "LRL_90_100"    "LRL_100_100"  
[29] "CoG"           "LRL.dec"       "LRL.dec.R2"    "LRL"           "LRno"          "aLRL"          "TRS"          
[36] "MRL.p.TRS"     "aLRL.p.TRS"    "LRL_10_perc"   "LRL_20_perc"   "LRL_30_perc"   "LRL_40_perc"   "LRL_50_perc"  
[43] "LRL_60_perc"   "LRL_70_perc"   "LRL_80_perc"   "LRL_90_perc"   "LRL_100_perc"  "LRno_10_perc"  "LRno_20_perc" 
[50] "LRno_30_perc"  "LRno_40_perc"  "LRno_50_perc"  "LRno_60_perc"  "LRno_70_perc"  "LRno_80_perc"  "LRno_90_perc" 
[57] "LRno_100_perc"

Cool - then let’s extract only the last day, reshape the data and plot the absolute LRno and LRL across the MR portions:

4 days after stress

day4 <- subset(LR_distribution, LR_distribution$DAS == 4)
head(day4)
colnames(day4)
 [1] "image"         "root_name"     "root"          "experiment"    "DAS"           "genotype"      "rep"          
 [8] "cond"          "LR_no_10_100"  "LR_no_20_100"  "LR_no_30_100"  "LR_no_40_100"  "LR_no_50_100"  "LR_no_60_100" 
[15] "LR_no_70_100"  "LR_no_80_100"  "LR_no_90_100"  "LR_no_100_100" "LRL_10_100"    "LRL_20_100"    "LRL_30_100"   
[22] "LRL_40_100"    "LRL_50_100"    "LRL_60_100"    "LRL_70_100"    "LRL_80_100"    "LRL_90_100"    "LRL_100_100"  
[29] "CoG"           "LRL.dec"       "LRL.dec.R2"    "LRL"           "LRno"          "aLRL"          "TRS"          
[36] "MRL.p.TRS"     "aLRL.p.TRS"    "LRL_10_perc"   "LRL_20_perc"   "LRL_30_perc"   "LRL_40_perc"   "LRL_50_perc"  
[43] "LRL_60_perc"   "LRL_70_perc"   "LRL_80_perc"   "LRL_90_perc"   "LRL_100_perc"  "LRno_10_perc"  "LRno_20_perc" 
[50] "LRno_30_perc"  "LRno_40_perc"  "LRno_50_perc"  "LRno_60_perc"  "LRno_70_perc"  "LRno_80_perc"  "LRno_90_perc" 
[57] "LRno_100_perc"
LRno <- day4[,c(1:18)]
head(LRno)
LRL <- day4[,c(1:8,19:28)]
library(reshape2)

Attaching package: ‘reshape2’

The following object is masked from ‘package:tidyr’:

    smiths
mLRno <- melt(LRno, value.name = "LRno")
Using image, root_name, root, experiment, DAS, genotype, rep, cond as id variables
mLRL <- melt(LRL, value.name = "LRL")
Using image, root_name, root, experiment, DAS, genotype, rep, cond as id variables
head(mLRno)
head(mLRL)

cool - now let’s adjust the portion of the MR that is being used to calculate the LR distribution in “variable” columns:

mLRno$variable <- gsub("LR_no_", "", mLRno$variable)
mLRno$variable <- gsub("_100", "", mLRno$variable)

mLRL$variable <- gsub("LRL_", "", mLRL$variable)
mLRL$variable <- gsub("_100", "", mLRL$variable)

mLRL$variable <- as.numeric(mLRL$variable)
mLRno$variable <- as.numeric(mLRno$variable)
colnames(mLRL)[9] <- "perc.of.MRL"
colnames(mLRno)[9] <- "perc.of.MRL"
head(mLRL)
head(mLRno)
NA
LRL_distribution_graph_d4 <- ggplot(data=mLRL, aes(x= perc.of.MRL, y=LRL, group = root_name, color = cond)) 
LRL_distribution_graph_d4 <- LRL_distribution_graph_d4 + geom_line(alpha = 0.1) + scale_colour_manual(values = c("dodgerblue3", "tomato1")) 
LRL_distribution_graph_d4 <- LRL_distribution_graph_d4 + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRL_distribution_graph_d4 <- LRL_distribution_graph_d4 + stat_summary(geom = "ribbon", linetype=0, fun.data = mean_cl_normal, aes(group= cond), alpha = 0.2)  + ggtitle("4 Days After Stress")
LRL_distribution_graph_d4 <- LRL_distribution_graph_d4 + theme(legend.position="none")+ labs(color = "Treatment")
LRL_distribution_graph_d4 <- LRL_distribution_graph_d4 + ylab("Lateral Root Length (cm)") + xlab("Portion of Main Root Length (%)") 
LRL_distribution_graph_d4 <- LRL_distribution_graph_d4 + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRL_distribution_graph_d4

LRno_distribution_graph_d4 <- ggplot(data=mLRno, aes(x= perc.of.MRL, y=LRno, group = root_name, color = cond)) 
LRno_distribution_graph_d4 <- LRno_distribution_graph_d4 + geom_line(alpha = 0.1) + scale_colour_manual(values = c("dodgerblue3", "tomato1")) 
LRno_distribution_graph_d4 <- LRno_distribution_graph_d4 + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRno_distribution_graph_d4 <- LRno_distribution_graph_d4 + stat_summary(geom = "ribbon", linetype=0, fun.data = mean_cl_normal, aes(group= cond), alpha = 0.2) + ggtitle("4 Days After Stress")
LRno_distribution_graph_d4 <- LRno_distribution_graph_d4 + theme(legend.position="none")+ labs(color = "Treatment")
LRno_distribution_graph_d4 <- LRno_distribution_graph_d4 + ylab("Lateral Root number") + xlab("Portion of Main Root Length (%)") 
LRno_distribution_graph_d4 <- LRno_distribution_graph_d4 + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRno_distribution_graph_d4

all good - but I think it would be better to calculate the above as %of LRL or %LRno per plant - then we can get better idea for clustering:

colnames(day4)
 [1] "image"         "root_name"     "root"          "experiment"    "DAS"           "genotype"      "rep"          
 [8] "cond"          "LR_no_10_100"  "LR_no_20_100"  "LR_no_30_100"  "LR_no_40_100"  "LR_no_50_100"  "LR_no_60_100" 
[15] "LR_no_70_100"  "LR_no_80_100"  "LR_no_90_100"  "LR_no_100_100" "LRL_10_100"    "LRL_20_100"    "LRL_30_100"   
[22] "LRL_40_100"    "LRL_50_100"    "LRL_60_100"    "LRL_70_100"    "LRL_80_100"    "LRL_90_100"    "LRL_100_100"  
[29] "CoG"           "LRL.dec"       "LRL.dec.R2"    "LRL"           "LRno"          "aLRL"          "TRS"          
[36] "MRL.p.TRS"     "aLRL.p.TRS"    "LRL_10_perc"   "LRL_20_perc"   "LRL_30_perc"   "LRL_40_perc"   "LRL_50_perc"  
[43] "LRL_60_perc"   "LRL_70_perc"   "LRL_80_perc"   "LRL_90_perc"   "LRL_100_perc"  "LRno_10_perc"  "LRno_20_perc" 
[50] "LRno_30_perc"  "LRno_40_perc"  "LRno_50_perc"  "LRno_60_perc"  "LRno_70_perc"  "LRno_80_perc"  "LRno_90_perc" 
[57] "LRno_100_perc"
LRno_perc <- day4[,c(1:8,48:57)]
LRL_perc <- day4[,c(1:8,38:47)]
head(LRno_perc)
head(LRL_perc)
mLRno_perc <- melt(LRno_perc, value.name = "LRno.perc")
Using image, root_name, root, experiment, DAS, genotype, rep, cond as id variables
mLRL_perc <- melt(LRL_perc, value.name = "LRL.perc")
Using image, root_name, root, experiment, DAS, genotype, rep, cond as id variables
head(mLRno_perc)
head(mLRL_perc)
unique(mLRno_perc$variable)
 [1] LRno_10_perc  LRno_20_perc  LRno_30_perc  LRno_40_perc  LRno_50_perc  LRno_60_perc  LRno_70_perc  LRno_80_perc 
 [9] LRno_90_perc  LRno_100_perc
10 Levels: LRno_10_perc LRno_20_perc LRno_30_perc LRno_40_perc LRno_50_perc LRno_60_perc ... LRno_100_perc
mLRno_perc$variable <- gsub("LRno_", "", mLRno_perc$variable)
mLRL_perc$variable <- gsub("LRL_", "", mLRL_perc$variable)

mLRno_perc$variable <- gsub("_perc", "", mLRno_perc$variable)
mLRL_perc$variable <- gsub("_perc", "", mLRL_perc$variable)

mLRno_perc$variable <- as.numeric(mLRno_perc$variable)
mLRL_perc$variable <- as.numeric(mLRL_perc$variable)

colnames(mLRno_perc)[9] <- "perc.of.MRL"
colnames(mLRL_perc)[9] <- "perc.of.MRL"
head(mLRno_perc)
head(mLRL_perc)

OK - now let’s recalculate these graphs:

LRL_distribution_graph_d4_perc <- ggplot(data=mLRL_perc, aes(x= perc.of.MRL, y=LRL.perc, group = root_name, color = cond)) 
LRL_distribution_graph_d4_perc <- LRL_distribution_graph_d4_perc + geom_line(alpha = 0.1) + scale_colour_manual(values = c("dodgerblue3", "tomato1")) 
LRL_distribution_graph_d4_perc <- LRL_distribution_graph_d4_perc + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRL_distribution_graph_d4_perc <- LRL_distribution_graph_d4_perc + stat_summary(geom = "ribbon", linetype=0, fun.data = mean_cl_normal, aes(group= cond), alpha = 0.2) + ggtitle("4 Days After Stress")
LRL_distribution_graph_d4_perc <- LRL_distribution_graph_d4_perc + theme(legend.position="none")+ labs(color = "Treatment")
LRL_distribution_graph_d4_perc <- LRL_distribution_graph_d4_perc + ylab("Lateral Root Length (fraction of total LRL)") + xlab("Portion of Main Root Length (%)") 
LRL_distribution_graph_d4_perc <- LRL_distribution_graph_d4_perc + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRL_distribution_graph_d4_perc



LRno_distribution_graph_d4_perc <- ggplot(data=mLRno_perc, aes(x= perc.of.MRL, y=LRno.perc, group = root_name, color = cond)) 
LRno_distribution_graph_d4_perc <- LRno_distribution_graph_d4_perc + geom_line(alpha = 0.1) + scale_colour_manual(values = c("dodgerblue3", "tomato1")) 
LRno_distribution_graph_d4_perc <- LRno_distribution_graph_d4_perc + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRno_distribution_graph_d4_perc <- LRno_distribution_graph_d4_perc + stat_summary(geom = "ribbon", linetype=0, fun.data = mean_cl_normal, aes(group= cond), alpha = 0.2) + ggtitle("4 Days After Stress")
LRno_distribution_graph_d4_perc <- LRno_distribution_graph_d4_perc + theme(legend.position="none")+ labs(color = "Treatment")
LRno_distribution_graph_d4_perc <- LRno_distribution_graph_d4_perc + ylab("Lateral Root number (fraction of total LR #)") + xlab("Portion of Main Root Length (%)") 
LRno_distribution_graph_d4_perc <- LRno_distribution_graph_d4_perc + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRno_distribution_graph_d4_perc

OK - so the percentage of LRL is definitely more informative. Let’s have a look how it looks in earlier days:

3 days after stress

day3 <- subset(all_MR3, all_MR3$DAS == 3)
LRno_perc <- day3[,c(1:8,48:57)]
LRL_perc <- day3[,c(1:8,38:47)]
mLRno_perc <- melt(LRno_perc, value.name = "LRno.perc")
Using image, root_name, root, experiment, DAS, genotype, rep, cond as id variables
mLRL_perc <- melt(LRL_perc, value.name = "LRL.perc")
Using image, root_name, root, experiment, DAS, genotype, rep, cond as id variables
mLRno_perc$variable <- gsub("LRno_", "", mLRno_perc$variable)
mLRL_perc$variable <- gsub("LRL_", "", mLRL_perc$variable)

mLRno_perc$variable <- gsub("_perc", "", mLRno_perc$variable)
mLRL_perc$variable <- gsub("_perc", "", mLRL_perc$variable)

mLRno_perc$variable <- as.numeric(mLRno_perc$variable)
NAs introduced by coercion
mLRL_perc$variable <- as.numeric(mLRL_perc$variable)
NAs introduced by coercion
colnames(mLRno_perc)[9] <- "perc.of.MRL"
colnames(mLRL_perc)[9] <- "perc.of.MRL"

LRL_distribution_graph_d3_perc <- ggplot(data=mLRL_perc, aes(x= perc.of.MRL, y=LRL.perc, group = root_name, color = cond)) 
LRL_distribution_graph_d3_perc <- LRL_distribution_graph_d3_perc + geom_line(alpha = 0.1) + scale_colour_manual(values = c("dodgerblue3", "tomato1")) + ylim(0,1)
LRL_distribution_graph_d3_perc <- LRL_distribution_graph_d3_perc + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRL_distribution_graph_d3_perc <- LRL_distribution_graph_d3_perc + stat_summary(geom = "ribbon", linetype=0, fun.data = mean_cl_normal, aes(group= cond), alpha = 0.2) + ggtitle("3 Days After Stress")
LRL_distribution_graph_d3_perc <- LRL_distribution_graph_d3_perc + theme(legend.position="none")+ labs(color = "Treatment")
LRL_distribution_graph_d3_perc <- LRL_distribution_graph_d3_perc + ylab("Lateral Root Length (fraction of total LRL)") + xlab("Portion of Main Root Length (%)") 
LRL_distribution_graph_d3_perc <- LRL_distribution_graph_d3_perc + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRL_distribution_graph_d3_perc



LRno_distribution_graph_d3_perc <- ggplot(data=mLRno_perc, aes(x= perc.of.MRL, y=LRno.perc, group = root_name, color = cond)) 
LRno_distribution_graph_d3_perc <- LRno_distribution_graph_d3_perc + geom_line(alpha = 0.1) + scale_colour_manual(values = c("dodgerblue3", "tomato1")) + ylim(0,1)
LRno_distribution_graph_d3_perc <- LRno_distribution_graph_d3_perc + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRno_distribution_graph_d3_perc <- LRno_distribution_graph_d3_perc + stat_summary(geom = "ribbon", linetype=0, fun.data = mean_cl_normal, aes(group= cond), alpha = 0.2) + ggtitle("3 Days After Stress")
LRno_distribution_graph_d3_perc <- LRno_distribution_graph_d3_perc + theme(legend.position="none")+ labs(color = "Treatment")
LRno_distribution_graph_d3_perc <- LRno_distribution_graph_d3_perc + ylab("Lateral Root number (fraction of total LR #)") + xlab("Portion of Main Root Length (%)") 
LRno_distribution_graph_d3_perc <- LRno_distribution_graph_d3_perc + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRno_distribution_graph_d3_perc

day2 <- subset(all_MR3, all_MR3$DAS == 2)
LRno_perc <- day2[,c(1:8,48:57)]
LRL_perc <- day2[,c(1:8,38:47)]
mLRno_perc <- melt(LRno_perc, value.name = "LRno.perc")
Using image, root_name, root, experiment, DAS, genotype, rep, cond as id variables
mLRL_perc <- melt(LRL_perc, value.name = "LRL.perc")
Using image, root_name, root, experiment, DAS, genotype, rep, cond as id variables
mLRno_perc$variable <- gsub("LRno_", "", mLRno_perc$variable)
mLRL_perc$variable <- gsub("LRL_", "", mLRL_perc$variable)

mLRno_perc$variable <- gsub("_perc", "", mLRno_perc$variable)
mLRL_perc$variable <- gsub("_perc", "", mLRL_perc$variable)

mLRno_perc$variable <- as.numeric(mLRno_perc$variable)
NAs introduced by coercion
mLRL_perc$variable <- as.numeric(mLRL_perc$variable)
NAs introduced by coercion
colnames(mLRno_perc)[9] <- "perc.of.MRL"
colnames(mLRL_perc)[9] <- "perc.of.MRL"

LRL_distribution_graph_d2_perc <- ggplot(data=mLRL_perc, aes(x= perc.of.MRL, y=LRL.perc, group = root_name, color = cond)) 
LRL_distribution_graph_d2_perc <- LRL_distribution_graph_d2_perc + geom_line(alpha = 0.1) + scale_colour_manual(values = c("dodgerblue3", "tomato1")) + ylim(0,1)
LRL_distribution_graph_d2_perc <- LRL_distribution_graph_d2_perc + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRL_distribution_graph_d2_perc <- LRL_distribution_graph_d2_perc + stat_summary(geom = "ribbon", linetype=0, fun.data = mean_cl_normal, aes(group= cond), alpha = 0.2) + ggtitle("2 Days After Stress")
LRL_distribution_graph_d2_perc <- LRL_distribution_graph_d2_perc + theme(legend.position="none")+ labs(color = "Treatment")
LRL_distribution_graph_d2_perc <- LRL_distribution_graph_d2_perc + ylab("Lateral Root Length (fraction of total LRL)") + xlab("Portion of Main Root Length (%)") 
LRL_distribution_graph_d2_perc <- LRL_distribution_graph_d2_perc + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRL_distribution_graph_d2_perc



LRno_distribution_graph_d2_perc <- ggplot(data=mLRno_perc, aes(x= perc.of.MRL, y=LRno.perc, group = root_name, color = cond)) 
LRno_distribution_graph_d2_perc <- LRno_distribution_graph_d2_perc + geom_line(alpha = 0.1) + scale_colour_manual(values = c("dodgerblue3", "tomato1")) + ylim(0,1)
LRno_distribution_graph_d2_perc <- LRno_distribution_graph_d2_perc + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRno_distribution_graph_d2_perc <- LRno_distribution_graph_d2_perc + stat_summary(geom = "ribbon", linetype=0, fun.data = mean_cl_normal, aes(group= cond), alpha = 0.2) + ggtitle("2 Days After Stress")
LRno_distribution_graph_d2_perc <- LRno_distribution_graph_d2_perc + theme(legend.position="none")+ labs(color = "Treatment")
LRno_distribution_graph_d2_perc <- LRno_distribution_graph_d2_perc + ylab("Lateral Root number (fraction of total LR #)") + xlab("Portion of Main Root Length (%)") 
LRno_distribution_graph_d2_perc <- LRno_distribution_graph_d2_perc + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRno_distribution_graph_d2_perc

day1 <- subset(all_MR3, all_MR3$DAS == 1)
LRno_perc <- day1[,c(1:8,48:57)]
LRL_perc <- day1[,c(1:8,38:47)]
mLRno_perc <- melt(LRno_perc, value.name = "LRno.perc")
Using image, root_name, root, experiment, DAS, genotype, rep, cond as id variables
mLRL_perc <- melt(LRL_perc, value.name = "LRL.perc")
Using image, root_name, root, experiment, DAS, genotype, rep, cond as id variables
mLRno_perc$variable <- gsub("LRno_", "", mLRno_perc$variable)
mLRL_perc$variable <- gsub("LRL_", "", mLRL_perc$variable)

mLRno_perc$variable <- gsub("_perc", "", mLRno_perc$variable)
mLRL_perc$variable <- gsub("_perc", "", mLRL_perc$variable)

mLRno_perc$variable <- as.numeric(mLRno_perc$variable)
NAs introduced by coercion
mLRL_perc$variable <- as.numeric(mLRL_perc$variable)
NAs introduced by coercion
colnames(mLRno_perc)[9] <- "perc.of.MRL"
colnames(mLRL_perc)[9] <- "perc.of.MRL"

LRL_distribution_graph_d1_perc <- ggplot(data=mLRL_perc, aes(x= perc.of.MRL, y=LRL.perc, group = root_name, color = cond)) 
LRL_distribution_graph_d1_perc <- LRL_distribution_graph_d1_perc + geom_line(alpha = 0.1) + scale_colour_manual(values = c("dodgerblue3", "tomato1")) + ylim(0,1)
LRL_distribution_graph_d1_perc <- LRL_distribution_graph_d1_perc + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRL_distribution_graph_d1_perc <- LRL_distribution_graph_d1_perc + stat_summary(geom = "ribbon", linetype=0, fun.data = mean_cl_normal, aes(group= cond), alpha = 0.2) + ggtitle("1 Day After Stress")
LRL_distribution_graph_d1_perc <- LRL_distribution_graph_d1_perc + theme(legend.position="none")+ labs(color = "Treatment")
LRL_distribution_graph_d1_perc <- LRL_distribution_graph_d1_perc + ylab("Lateral Root Length (fraction of total LRL)") + xlab("Portion of Main Root Length (%)") 
LRL_distribution_graph_d1_perc <- LRL_distribution_graph_d1_perc + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRL_distribution_graph_d1_perc



LRno_distribution_graph_d1_perc <- ggplot(data=mLRno_perc, aes(x= perc.of.MRL, y=LRno.perc, group = root_name, color = cond)) 
LRno_distribution_graph_d1_perc <- LRno_distribution_graph_d1_perc + geom_line(alpha = 0.1) + scale_colour_manual(values = c("dodgerblue3", "tomato1")) + ylim(0,1)
LRno_distribution_graph_d1_perc <- LRno_distribution_graph_d1_perc + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
LRno_distribution_graph_d1_perc <- LRno_distribution_graph_d1_perc + stat_summary(geom = "ribbon", linetype=0, fun.data = mean_cl_normal, aes(group= cond), alpha = 0.2) + ggtitle("1 Day After Stress")
LRno_distribution_graph_d1_perc <- LRno_distribution_graph_d1_perc + theme(legend.position="none")+ labs(color = "Treatment")
LRno_distribution_graph_d1_perc <- LRno_distribution_graph_d1_perc + ylab("Lateral Root number (fraction of total LR #)") + xlab("Portion of Main Root Length (%)") 
LRno_distribution_graph_d1_perc <- LRno_distribution_graph_d1_perc + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
LRno_distribution_graph_d1_perc

ok - maybe let’s combine these graphs into a figure thus far:

library(cowplot)
pdf("Fig.Lateral_root_distribution_across_MRL_DAS1_DAS4_Big01_to_Big04.pdf", height = 20, width = 15)
plot_grid(LRL_distribution_graph_d1_perc, LRno_distribution_graph_d1_perc,
          LRL_distribution_graph_d2_perc, LRno_distribution_graph_d2_perc,
          LRL_distribution_graph_d3_perc, LRno_distribution_graph_d3_perc,
          LRL_distribution_graph_d4_perc, LRno_distribution_graph_d4_perc, ncol=2, labels = "AUTO")
Removed 8409 rows containing non-finite values (stat_summary).Removed 8409 rows containing non-finite values (stat_summary).Removed 8409 rows containing non-finite values (stat_compare_means).Removed 8381 row(s) containing missing values (geom_path).Removed 8409 rows containing non-finite values (stat_summary).Removed 8409 rows containing non-finite values (stat_summary).Removed 8409 rows containing non-finite values (stat_compare_means).Removed 8381 row(s) containing missing values (geom_path).Removed 8072 rows containing non-finite values (stat_summary).Removed 8072 rows containing non-finite values (stat_summary).Removed 8072 rows containing non-finite values (stat_compare_means).Removed 8056 row(s) containing missing values (geom_path).Removed 8072 rows containing non-finite values (stat_summary).Removed 8072 rows containing non-finite values (stat_summary).Removed 8072 rows containing non-finite values (stat_compare_means).Removed 8056 row(s) containing missing values (geom_path).Removed 7825 rows containing non-finite values (stat_summary).Removed 7825 rows containing non-finite values (stat_summary).Removed 7825 rows containing non-finite values (stat_compare_means).Removed 7823 row(s) containing missing values (geom_path).Removed 7825 rows containing non-finite values (stat_summary).Removed 7825 rows containing non-finite values (stat_summary).Removed 7825 rows containing non-finite values (stat_compare_means).Removed 7823 row(s) containing missing values (geom_path).Removed 120 rows containing non-finite values (stat_summary).Removed 120 rows containing non-finite values (stat_summary).Removed 120 rows containing non-finite values (stat_compare_means).Removed 120 row(s) containing missing values (geom_path).Removed 120 rows containing non-finite values (stat_summary).Removed 120 rows containing non-finite values (stat_summary).Removed 120 rows containing non-finite values (stat_compare_means).Removed 120 row(s) containing missing values (geom_path).
dev.off()
null device 
          1 

Calculating growth rates for each plant:

OK - so now we have all the data organized and everything seems to look pretty sane - let’s start calculating the growth rate of aLRL, LR# and MR. The problem is that in some cases - the MR grew into the plate - and we didnt continue tracing it - so the length is getting staled. So - in these cases - I would like to calculate the growth rate only over the period where the size of the root is actually increasing. So:

First - set the “day” ad numeric variable - because this will later come and bite us in our asses:

all_MR3$DAS <- as.numeric(as.character(all_MR3$DAS))
head(all_MR3)

Establishing calculations

Second - isolate one plant from the dataset, sort per day, and mark which of the values for MR are duplicates:

temp1 <- subset(all_MR3, all_MR3$root == unique(all_MR3$root)[100])
temp2 <- temp1[order(temp1$DAS),]
head(temp2)

temp2$MRdouble <- "no"
for(i in 2:5){
 if(temp2$MRL[i] == temp2$MRL[i-1]){
  temp2$MRdouble[i] <- "yes"   
 } 
  else{
  temp2$MRdouble[i] <- "no"   
 } 
}

temp3 <- subset(temp2, temp2$MRdouble == "no")
temp3

Now that we have the dataset without duplicated values - let’s calculate MR growth rate using linear function:

plot(temp3$MRL ~ temp3$DAS)
abline(lm(temp3$MRL ~ temp3$DAS))

Let’s check if this is also true for #LR:

temp2$LRnodouble <- "no"
for(i in 2:5){
 if(temp2$LRno[i] == temp2$LRno[i-1]){
  temp2$LRnodouble[i] <- "yes"   
 } 
  else{
  temp2$LRnodouble[i] <- "no"   
 } 
}

temp3 <- subset(temp2, temp2$LRnodouble == "no")

plot(temp3$LRno ~ temp3$DAS)
abline(lm(temp3$LRno ~ temp3$DAS))

and for aLRL:

temp2$aLRLdouble <- "no"
for(i in 2:5){
 if(temp2$aLRL[i] == temp2$aLRL[i-1]){
  temp2$aLRLdouble[i] <- "yes"   
 } 
  else{
  temp2$aLRLdouble[i] <- "no"   
 } 
}
temp2

temp3 <- subset(temp2, temp2$aLRLdouble == "no")

plot(temp3$aLRL ~ temp3$DAS)
abline(lm(temp3$aLRL ~ temp3$DAS))

Looped linear modeling for all RSA components

First - let’s construct the dataframe which will hold all the data points:

names <- c(text="root_name", "genotype", "cond", "MR.intercept", "MR.delta", "LRno.intercept", "LRno.delta", "aLRL.intercept", "aLRL.delta")
growth_factors <- data.frame()

for (k in names) growth_factors[[k]] <- as.character()

just few fixes:

all_MR3$root_name<- gsub("2800_3_S", "280_3_S", all_MR3$root_name)
all_MR3 <- subset(all_MR3, all_MR3$image != "_set1_day1_20190930_093.rsml")
all_MR3 <- subset(all_MR3, all_MR3$image != "_set1_day1_20190930_090.rsml") 
all_MR3 <- subset(all_MR3, all_MR3$image != "_set1_day1_20190930_067.rsml")
all_MR3 <- subset(all_MR3, all_MR3$image != "_set1_day1_20191008_047_FU.rsml")

Then - let’s loop it in for calculating the Main Root growth factors:

for(e in c(1:length(unique(all_MR3$root_name)))){
  temp1 <- subset(all_MR3, all_MR3$root_name == unique(all_MR3$root_name)[e])
  temp2 <- temp1[order(temp1$DAS),]
  dim(temp2)
  if(dim(temp2)[1] < 2){
    
  }
  
  # Main root part
  temp2$MRdouble <- "no"
  for(i in 2:nrow(temp2)){
   if(temp2$MRL[i] == temp2$MRL[i-1]){
    temp2$MRdouble[i] <- "yes"   
   } 
    else{
    temp2$MRdouble[i] <- "no"   
   } 
  }
  
  temp2
  # Main Root Growth Factor calculations: 
  temp3 <- subset(temp2, temp2$MRdouble == "no")
  model <- lm(temp3$MRL ~ temp3$DAS)
  growth_factors[e,1] <- temp3$root_name[1]
  growth_factors[e,2] <- temp3$genotype[1]
  growth_factors[e,3] <- temp3$cond[1]
  growth_factors[e,4] <- as.numeric(as.character(model$coefficients[[1]]))
  growth_factors[e,5] <- as.numeric(as.character(model$coefficients[[2]]))
  
 
}
dim(growth_factors)
[1] 1072    9

Great - let’s calculate the LRno increase rate - with some special conditions for the lines which don’t have any LR:

for(e in 1:length(unique(all_MR3$root_name))){
  temp1 <- subset(all_MR3, all_MR3$root_name == unique(all_MR3$root_name)[e])
  temp2 <- temp1[order(temp1$DAS),]

 # Let's remove all NA for LRno and aLRL in temp2
  super_temp <- temp2[,c("DAS", "LRno", "aLRL")]
  temp2 <- na.omit(super_temp)
  
  if(dim(temp2)[1] > 1){
    model <- lm(temp2$LRno ~ temp2$DAS)
    growth_factors[e,6] <- as.numeric(as.character(model$coefficients[[1]]))
    growth_factors[e,7] <- as.numeric(as.character(model$coefficients[[2]]))  
  }
  # Lateral Root Number Increase calculations:
  else{
    growth_factors[e,6] <- 0
    growth_factors[e,7] <- 0
  }
}  

Same thing for aLRL:

for(e in 1:length(unique(all_MR3$root_name))){
  temp1 <- subset(all_MR3, all_MR3$root_name == unique(all_MR3$root_name)[e])
  temp2 <- temp1[order(temp1$DAS),]

 # Let's remove all NA for LRno and aLRL in temp2
  super_temp <- temp2[,c("DAS", "LRno", "aLRL")]
  temp2 <- na.omit(super_temp)
  temp2
  dim(temp2)[1]
  if(dim(temp2)[1] > 1){
    model <- lm(temp2$aLRL ~ temp2$DAS)
    model
    growth_factors[e,8] <- as.numeric(as.character(model$coefficients[[1]]))
    growth_factors[e,9] <- as.numeric(as.character(model$coefficients[[2]]))  
  }
  # Lateral Root Number Increase calculations:
  else{
    growth_factors[e,8] <- 0
    growth_factors[e,9] <- 0
  }
}  

Let’s have a look at the growth_factors table:

growth_factors
min(growth_factors$MR.delta)
[1] "-0.1994374"
min(growth_factors$LRno.delta)
[1] NA
min(growth_factors$aLRL.delta)
[1] NA
max(growth_factors$MR.delta)
[1] "3.24117685"
max(growth_factors$LRno.delta)
[1] NA
max(growth_factors$aLRL.delta)
[1] NA
sapply(growth_factors, class)
     root_name       genotype           cond   MR.intercept       MR.delta LRno.intercept     LRno.delta 
   "character"    "character"    "character"    "character"    "character"    "character"    "character" 
aLRL.intercept     aLRL.delta 
   "character"    "character" 
growth_factors$MR.delta <- as.numeric(growth_factors$MR.delta)
growth_factors$LRno.delta <- as.numeric(growth_factors$LRno.delta)
growth_factors$aLRL.delta <- as.numeric(growth_factors$aLRL.delta)

Histograms for growth rates

Most values seem to be in the reasonable range - but let’s have a look at the histogram

MR.delta_histo <- gghistogram(growth_factors, x = "MR.delta",
            add = "mean", rug = TRUE,
            color = "cond", fill = "cond", 
            palette = c("#00AFBB", "#E7B800")) + xlab("Main Root Growth (cm / day)")
Using `bins = 30` by default. Pick better value with the argument `bins`.
MR.delta_histo

LRno.delta_histo <- gghistogram(growth_factors, x = "LRno.delta",
            add = "mean", rug = TRUE,
            color = "cond", fill = "cond", 
            palette = c("#00AFBB", "#E7B800")) + xlab("Increase in Lateral Root number (# LR / day)")
Using `bins = 30` by default. Pick better value with the argument `bins`.
LRno.delta_histo

aLRL.delta_histo <- gghistogram(growth_factors, x = "aLRL.delta",
            add = "mean", rug = TRUE,
            color = "cond", fill = "cond", 
            palette = c("#00AFBB", "#E7B800")) + xlab("average Lateral Root Growth (cm / day)")
Using `bins = 30` by default. Pick better value with the argument `bins`.
aLRL.delta_histo

awesome - let’s save this into one figure as well:

pdf("Fig.Growth_rates_histograms_MR_noLR_aLRL.pdf", width = 7.5, height = 10)
plot_grid(MR.delta_histo, LRno.delta_histo, aLRL.delta_histo, ncol=1, labels = "AUTO")
Removed 1 rows containing non-finite values (stat_bin).Removed 1 rows containing non-finite values (stat_bin).
dev.off()
null device 
          1 

reproducibility within accessions for growth rates:

let’s have a look what is the diversity of growth rates within accessions:

grand.means <- aggregate(MR.delta ~ cond, data = growth_factors, FUN = mean)
grand.means

unique(growth_factors$genotype)
  [1] " 189" " 292" " 213" " 212" " 307" " 282" " 298" " 301" " 286" " 214" " 194" " 294" " 285" " 293" " 284" " 278"
 [17] " 300" " 201" " 279" " 280" " 299" " 200" " 211" " 308" " 197" " 287" " 196" " 220" " 207" " 290" " 198" " 195"
 [33] " 289" " 288" " 291" " 199" " 277" " 283" " 306" " 235" " 192" " 147" " 252" " 166" " 269" " 064" " 253" " 193"
 [49] " 146" " 141" " 251" " 139" " 169" " 258" " 144" " 138" " 061" " 065" " 170" " 142" " 140" " 168" " 272" " 165"
 [65] " 255" " 260" " 264" " 262" " 261" " 167" " 060" " 066" " 136" " 256" " 143" " 171" " 082" " 083" " 191" " 259"
 [81] " 062" " 172" " 063" " 270" " 268" " 267" " 234" " 245" " 173" " 236" " 084" " 229" " 241" " 231" " 227" " 176"
 [97] " 087" " 091" " 090" " 085" " 228" " 230" " 175" " 250" " 222" " 239" " 233" " 274" " 088" " 271" " 240" " 092"
[113] " 089" " 247" " 038" " 248" " 086" " 273" " 244" " 093" " 174" " 249" " 237" " 221" " 225" " 103" " 028" " 098"
[129] " 055" " 075" " 059" " 101" " 034" " 002" " 030" " 056" " 001" " 102" " 012" " 076" " 079" " 104" " 081" " 096"
[145] " 058" " 099" " 105" " 040" " 035" " 094" " 074" " 032" " 022" " 003" " 095" " 009" " 106" " 057" " 033" " 029"
[161] " 013" " 031" " 007" " 008" " 006" " 080" " 005" " 036" " 011" " 078" " 010" " 097" " 037"
MR.delta_p_geno <- ggerrorplot(growth_factors, y = "MR.delta", x = "genotype", fill="genotype", color="genotype", 
                        facet.by = c("cond"), ncol=1,
                        desc_stat = "mean_sd", add = "jitter", 
                        add.params = list(color = "darkgray"),
                        xlab="Genotype", ylab="Main Root Growth (cm / day)") 
MR.delta_p_geno <- MR.delta_p_geno + geom_hline(
                          data = grand.means, aes(yintercept = MR.delta),
                          linetype = 2,
                          group = "cond")
MR.delta_p_geno <- MR.delta_p_geno + rremove("legend") + stat_compare_means(method="t.test", ref.group = ".all.", 
                                                              label = "p.signif", hide.ns = T)
MR.delta_p_geno

grand.means <- aggregate(LRno.delta ~ cond, data = growth_factors, FUN = mean)
grand.means

LRno.delta_p_geno <- ggerrorplot(growth_factors, y = "LRno.delta", x = "genotype", fill="genotype", color="genotype", 
                        facet.by = c("cond"), ncol=1,
                        desc_stat = "mean_sd", add = "jitter", 
                        add.params = list(color = "darkgray"),
                        xlab="Genotype", ylab="Increase in LR number (# LR / day)") 
LRno.delta_p_geno <- LRno.delta_p_geno + geom_hline(
                          data = grand.means, aes(yintercept = LRno.delta),
                          linetype = 2,
                          group = "cond")
LRno.delta_p_geno <- LRno.delta_p_geno + rremove("legend") + stat_compare_means(method="t.test", ref.group = ".all.", 
                                                              label = "p.signif", hide.ns = T)
LRno.delta_p_geno

grand.means <- aggregate(aLRL.delta ~ cond, data = growth_factors, FUN = mean)
grand.means

aLRL.delta_p_geno <- ggerrorplot(growth_factors, y = "aLRL.delta", x = "genotype", fill="genotype", color="genotype", 
                        facet.by = c("cond"), ncol=1,
                        desc_stat = "mean_sd", add = "jitter", 
                        add.params = list(color = "darkgray"),
                        xlab="Genotype", ylab="average Lateral Root Growth (cm / day)") 
aLRL.delta_p_geno <- aLRL.delta_p_geno + geom_hline(
                          data = grand.means, aes(yintercept = aLRL.delta),
                          linetype = 2,
                          group = "cond")
aLRL.delta_p_geno <- aLRL.delta_p_geno + rremove("legend") + stat_compare_means(method="t.test", ref.group = ".all.", 
                                                              label = "p.signif", hide.ns = T)
aLRL.delta_p_geno

ok - but these trends are very general - let’s have a look what is the diversity between accessions in their salt responses.

stress-induced changes in growth rates:

Also - maybe lets calculate the average growth rate per accession and look how this looks on a graph with some stats - as in - do we see sig. differences between C and S:

head(growth_factors)
growth_nona <- na.omit(growth_factors)
sum_growth <- summaryBy(data = growth_factors, MR.delta + LRno.delta + aLRL.delta ~ cond + genotype)
sum_growth

MR.delta_dotplot <- ggerrorplot(sum_growth, y = "MR.delta.mean", x = "cond", fill="cond", color="cond", 
                        desc_stat = "mean_sd", add = "jitter", 
                        add.params = list(color = "darkgray"),
                        xlab="Condition", ylab="Main Root Growth (cm / day)") 
MR.delta_dotplot <- MR.delta_dotplot + rremove("legend") + stat_compare_means(method="t.test", ref.group = "C", 
                                                              label = "p.signif", hide.ns = T)
MR.delta_dotplot

aLRL.delta_dotplot <- ggerrorplot(sum_growth, y = "aLRL.delta.mean", x = "cond", fill="cond", color="cond", 
                        desc_stat = "mean_sd", add = "jitter", 
                        add.params = list(color = "darkgray"),
                        xlab="Condition", ylab="average Lateral Root Growth (cm / day)") 
aLRL.delta_dotplot <- aLRL.delta_dotplot + rremove("legend") + stat_compare_means(method="t.test", ref.group = "C", 
                                                              label = "p.signif", hide.ns = T)
aLRL.delta_dotplot

LRno.delta_dotplot <- ggerrorplot(sum_growth, y = "LRno.delta.mean", x = "cond", fill="cond", color="cond", 
                        desc_stat = "mean_sd", add = "jitter", 
                        add.params = list(color = "darkgray"),
                        xlab="Condition", ylab="average Lateral Root Growth (cm / day)") 
LRno.delta_dotplot <- LRno.delta_dotplot + rremove("legend") + stat_compare_means(method="t.test", ref.group = "C", 
                                                              label = "p.signif", hide.ns = T)
LRno.delta_dotplot

ok - now we have all the accession values averaged - let’s compare the growth rate under control and salt stress

First - we need to split the data into control and salt and then match them based on genotype:

growth_C <- subset(sum_growth, sum_growth$cond == "C")
growth_S <- subset(sum_growth, sum_growth$cond == "S")
colnames(growth_C) <- gsub(".mean", ".Control", colnames(growth_C))
colnames(growth_S) <- gsub(".mean", ".Salt", colnames(growth_S))

growth_C2 <- growth_C[,c(2:5)]
growth_S2 <- growth_S[,c(2:5)]

sum_growth2 <- merge(growth_C2, growth_S2, by="genotype")
sum_growth2
corrplot_MR_gr <- ggscatter(sum_growth2, x = "MR.delta.Control", y = "MR.delta.Salt", size = 0.3, 
                            rug = TRUE, add = "reg.line", color = "LRno.delta.Control") + stat_cor(method = "pearson")
corrplot_MR_gr <- corrplot_MR_gr + gradient_color(c("blue", "grey", "red"))
corrplot_MR_gr

corrplot_aLRL_gr <- ggscatter(sum_growth2, x = "aLRL.delta.Control", y = "aLRL.delta.Salt", size = 0.3, 
                            rug = TRUE, add = "reg.line", color = "aLRL.delta.Control") + stat_cor(method = "pearson")
corrplot_aLRL_gr <- corrplot_aLRL_gr + gradient_color(c("blue", "grey", "red"))
corrplot_aLRL_gr

NA
NA
corrplot_LRno_gr <- ggscatter(sum_growth2, x = "LRno.delta.Control", y = "LRno.delta.Salt", color = "LRno.delta.Control",
                              size = 0.3, rug = TRUE, add = "reg.line") + stat_cor(method = "pearson")
corrplot_LRno_gr <- corrplot_LRno_gr + gradient_color(c("blue", "grey", "red"))
corrplot_LRno_gr

hmmm… thinking about the dotplots from earlier and they should actually be a paired graph, because we want to see how individual accessions are behaving, and whether that behaviour is conserved across accessions:

MR_sum_growth <- sum_growth2[,c(1,2,5)]
MR_sum_melt <- melt(MR_sum_growth)
Using genotype as id variables
MR_sum_melt
MR_sum_melt$variable <- gsub("MR.delta.", "", MR_sum_melt$variable)
colnames(MR_sum_melt)[2] <- "condition"
colnames(MR_sum_melt)[3] <- "MR.delta"


MR_growth_paired <- ggpaired(MR_sum_melt, x = "condition", y = "MR.delta",
                               color = "condition", line.color = "gray", line.size = 0.1,
                               palette = "jco", xlab ="", ylab ="Main Root Growth (cm / day)")
MR_growth_paired <- MR_growth_paired + stat_compare_means(paired = TRUE, label.x = 1.5) + rremove("legend")
MR_growth_paired

Cool - that looks much more informative - let’s do this for other traits:

LRno_sum_growth <- sum_growth2[,c(1,3,6)]
LRno_sum_growth <- na.omit(LRno_sum_growth)
LRno_sum_melt <- melt(LRno_sum_growth)
Using genotype as id variables
LRno_sum_melt
LRno_sum_melt$variable <- gsub("LRno.delta.", "", LRno_sum_melt$variable)
colnames(LRno_sum_melt)[2] <- "condition"
colnames(LRno_sum_melt)[3] <- "LRno.delta"


LRno_growth_paired <- ggpaired(LRno_sum_melt, x = "condition", y = "LRno.delta",
                               color = "condition", line.color = "gray", line.size = 0.1,
                               palette = "jco", xlab ="", ylab ="Increase in Lateral Root # (# LR / day)")
LRno_growth_paired <- LRno_growth_paired + stat_compare_means(paired = TRUE, label.x = 1.5) + rremove("legend")
LRno_growth_paired

aLRL_sum_growth <- sum_growth2[,c(1,4,7)]
aLRL_sum_growth <- na.omit(aLRL_sum_growth)
aLRL_sum_melt <- melt(aLRL_sum_growth)
Using genotype as id variables
aLRL_sum_melt
aLRL_sum_melt$variable <- gsub("aLRL.delta.", "", aLRL_sum_melt$variable)
colnames(aLRL_sum_melt)[2] <- "condition"
colnames(aLRL_sum_melt)[3] <- "aLRL.delta"


aLRL_growth_paired <- ggpaired(aLRL_sum_melt, x = "condition", y = "aLRL.delta",
                               color = "condition", line.color = "gray", line.size = 0.1,
                               palette = "jco", xlab ="", ylab ="average Lateral Root Growth (cm / day)")
aLRL_growth_paired <- aLRL_growth_paired + stat_compare_means(paired = TRUE, label.x = 1.5) + rremove("legend")
aLRL_growth_paired

ok - now let’s start comparing how individual accessions are doing when it comes to salt indices of individual organs:

Salt Tolerance Indexes

In order to look at salt responses - we need to calculate the average plant responses per accession and calculate the relative change in growth rate in response to salt (relative to control):

head(sum_growth2)

sum_growth2$MR.STI <- sum_growth2$MR.delta.Salt/sum_growth2$MR.delta.Control
sum_growth2$LRno.STI <- sum_growth2$LRno.delta.Salt/sum_growth2$LRno.delta.Control
sum_growth2$aLRL.STI <- sum_growth2$aLRL.delta.Salt/sum_growth2$aLRL.delta.Control
head(sum_growth2)

Then - we would like to know also what is the effect of the salt on different root components across different accessions - so let’s make a histogram for this :)

colnames(sum_growth2)
 [1] "genotype"           "MR.delta.Control"   "LRno.delta.Control" "aLRL.delta.Control" "MR.delta.Salt"     
 [6] "LRno.delta.Salt"    "aLRL.delta.Salt"    "MR.STI"             "LRno.STI"           "aLRL.STI"          
STI_histo_set <- sum_growth2[,c(1,8:10)]
head(STI_histo_set)
STI_histo_melt <- melt(STI_histo_set)
Using genotype as id variables
head(STI_histo_melt)

STI_growth_histo <- gghistogram(STI_histo_melt, x = "value",
            add = "mean", rug = TRUE,
            color = "variable", fill = "variable", 
            palette = c("#1b9e77", "#d95f02", "#7570b3")) + xlab("fraction of growth at control")
Using `bins = 30` by default. Pick better value with the argument `bins`.
STI_growth_histo

cool - now we can also look in detail of how the individual accessions behave throughout these three STI

STI_growth_paired <- ggpaired(STI_histo_melt, x = "variable", y = "value",
                               color = "variable", line.color = "gray", line.size = 0.1,
                               palette = "jco", xlab ="", ylab ="Fraction of rate at Control")
STI_growth_paired <- STI_growth_paired + stat_compare_means(paired = TRUE, label.x = 1.5) + rremove("legend")
STI_growth_paired

ok - also - lets look at these things in a bit more traditional setting:

sum_growth2
STI_MR_vs_aLRL <- ggscatter(sum_growth2, x = "MR.STI", y = "aLRL.STI", color = "aLRL.delta.Control", size = 0.3, 
                            rug = TRUE, add = "reg.line") + stat_cor(method = "pearson")
STI_MR_vs_aLRL <- STI_MR_vs_aLRL + gradient_color(c("blue", "grey", "red"))

STI_MR_vs_aLRL

STI_MR_vs_LRno <- ggscatter(sum_growth2, x = "MR.STI", y = "LRno.STI", color = "LRno.delta.Control", size = 0.3, 
                            rug = TRUE, add = "reg.line") + stat_cor(method = "pearson")
STI_MR_vs_LRno <- STI_MR_vs_LRno + gradient_color(c("blue", "grey", "red"))

STI_MR_vs_LRno

STI_aLRL_vs_LRno <- ggscatter(sum_growth2, x = "aLRL.STI", y = "LRno.STI", color = "LRno.delta.Control", size = 0.3, 
                            rug = TRUE, add = "reg.line") + stat_cor(method = "pearson")
STI_aLRL_vs_LRno <- STI_aLRL_vs_LRno + gradient_color(c("blue", "grey", "red"))

STI_aLRL_vs_LRno

Conclusions so far

OK - so all of the above is pretty interesting - from the paired STI graph we can tell that there are multiple classes of accessions:

STI_growth_paired

  1. accessions that are equally impaired for all components of RSA
  2. accessions that are LEAST impaired in MRL
  3. accessions that are MOST impaired in MRL
  4. accessions that are MOST impaired in LRno

The correlations between individual SITs is very low for all combinations - which is pretty exciting, and aLRL and MRL are in general the least impacted by the salt stress - while LRno is impaired in most accessions the most - based on this histogram:

STI_growth_histo

now - I am wondering - if we throw only the STI into the hierarchical clustering - would we be able to discern between these classes of accessions?

Let’s see:

Hclust based on the SITs:

First - let’s prepare the matrix:

colnames(sum_growth2)
 [1] "genotype"           "MR.delta.Control"   "LRno.delta.Control" "aLRL.delta.Control" "MR.delta.Salt"     
 [6] "LRno.delta.Salt"    "aLRL.delta.Salt"    "MR.STI"             "LRno.STI"           "aLRL.STI"          
STI_only <- sum_growth2[,c(1,8:10)]
# get only numeric variables from your data - NOT plant identifiers 
STI_matrix <- STI_only[, c(2:4)]
# transfer all numeric variables into matrix
STI_matrix2 <- as.matrix(STI_matrix)
# add plant identifiers as row names
row.names(STI_matrix2) <- STI_only$genotype
# omit missing values - otherwise we wont be able to do the clustering 
final_m <- na.omit(STI_matrix2)
dim(STI_matrix2)
[1] 170   3
dim(final_m)
[1] 169   3
head(final_m)
        MR.STI  LRno.STI  aLRL.STI
 001 1.2207550 0.2886179 0.9878750
 002 1.7812165 0.8893443 0.6813830
 003 0.6241646 0.5460317 0.9047426
 005 0.8284342 1.3500000 0.6491019
 006 1.2725551 0.4566210 0.5787553
 007 1.0796448 0.2659574 1.1628734
# run a correlation
magda_cor = cor(final_m,method=c("pearson"))
# calculate distance
magda_dist = dist(magda_cor)
# this is the clustering itself - but now we are clustering how phenotypes are related to eachother
magda_clust = hclust(magda_dist,method="ward.D2")
plot(as.dendrogram(magda_clust),horiz=T)

# transposing the matrix
magda_t_matrix=t(final_m)
magda_t_cor = cor(magda_t_matrix,method=c("pearson"))
magda_t_dist = dist(magda_t_cor)
# clustering of accessions
magda_t_clust = hclust(magda_t_dist,method="ward.D2")
plot(as.dendrogram(magda_t_clust),horiz=T)

clusters <- cutree(magda_t_clust,h=24)
unique(clusters)
[1] 1 2 3 4 5
write.table(as.data.frame(cutree(magda_t_clust,h=24)),file="STI_clusters.txt",sep="\t",quote=F)
# the scaling only now applies to "row" which are our different phenotypes
heatmap.2(magda_t_matrix,Rowv=as.dendrogram(magda_clust),Colv=as.dendrogram(magda_t_clust),col=blue2red(100),scale=c("row"),density.info="none",trace="none")

OK - let’s save this one into a file before we forget

pdf("Fig.STI_clustering.pdf",width=12,height=7)
heatmap.2(magda_t_matrix,Rowv=as.dendrogram(magda_clust),Colv=as.dendrogram(magda_t_clust),col=blue2red(100),scale=c("row"),density.info="none",trace="none")
dev.off()
null device 
          1 

cool - now let’s see if the clusters actually differ in their respective growth rates / STIs.

First - let’s fuse “clusters” with the other growth rate data

clusters
 001  002  003  005  006  007  008  009  010  011  012  013  028  029  030  031  032  033  034  035  036  037  038 
   1    1    2    3    1    4    2    4    1    2    4    4    4    4    1    5    2    5    1    4    1    2    2 
 040  055  056  057  058  059  060  061  062  063  065  066  074  075  076  078  079  080  081  082  083  084  085 
   4    4    2    1    1    5    4    4    2    3    5    5    2    4    4    1    1    1    4    1    1    2    1 
 086  087  088  089  090  091  092  093  094  095  096  097  098  099  101  102  103  104  105  106  136  138  139 
   1    1    2    2    5    1    1    1    2    2    1    2    2    2    1    2    1    1    4    4    2    4    2 
 140  141  142  143  144  146  147  165  166  167  168  169  170  171  172  173  174  175  176  191  192  193  194 
   2    1    1    1    1    2    5    1    4    2    2    4    4    4    5    2    5    1    2    2    4    2    1 
 195  196  197  198  199  200  201  207  211  212  213  214  220  221  222  225  227  228  229  230  231  233  234 
   4    2    2    2    5    5    5    2    2    2    1    4    1    1    2    1    5    4    4    5    4    4    3 
 235  236  237  239  240  241  244  245  247  248  249  250  251  252  253  255  256  258  259  260  261  262  264 
   1    1    1    4    1    4    5    4    1    2    5    1    2    2    1    2    1    1    5    2    1    1    3 
 267  268  269  270  271  272  273  274  277  278  279  280  282  283  284  285  286  287  288  290  291  292  293 
   3    1    1    1    4    2    1    1    2    1    4    2    2    2    2    1    4    1    4    1    1    4    1 
 294  298  299  300  301  306  307  308 
   1    1    5    2    5    1    5    1 
sumatrix <- sum_growth2[,c(2:10)]
sumatrix2 <- as.matrix(sumatrix)
row.names(sumatrix2) <- sum_growth2$genotype
sumatrix3 <- na.omit(sumatrix2)

sum_growth3 <- cbind(sumatrix3, clusters)
head(sum_growth3)
     MR.delta.Control LRno.delta.Control aLRL.delta.Control MR.delta.Salt LRno.delta.Salt aLRL.delta.Salt    MR.STI
 001        1.2059372           6.150000          0.1881415     1.4721539       1.7750000       0.1858603 1.2207550
 002        0.7807096           2.033333          0.6265680     1.3906129       1.8083333       0.4269328 1.7812165
 003        1.2698976           5.250000          0.2862967     0.7926251       2.8666667       0.2590248 0.6241646
 005        1.2294472           3.833333          0.4431234     1.0185161       5.1750000       0.2876322 0.8284342
 006        1.2223445           7.300000          0.2833526     1.5555007       3.3333333       0.1639918 1.2725551
 007        0.6433493           3.133333          0.3487621     0.6945888       0.8333333       0.4055662 1.0796448
      LRno.STI  aLRL.STI clusters
 001 0.2886179 0.9878750        1
 002 0.8893443 0.6813830        1
 003 0.5460317 0.9047426        2
 005 1.3500000 0.6491019        3
 006 0.4566210 0.5787553        1
 007 0.2659574 1.1628734        4

ok - now let’s make some graphs per clusters starting with STIs:

growth_cluster3 <- as.data.frame(sum_growth3)
growth_cluster3

STIcluster_MR.STI <- ggerrorplot(growth_cluster3, y = "MR.STI", x = "clusters", fill="clusters", 
                                   color="clusters", desc_stat = "mean_sd", add = "jitter", 
                                   add.params = list(color = "darkgray"), xlab="", 
                                   ylab="Fraction of Control (Main Root Growth)", title = "Main Root STI") 
STIcluster_MR.STI <- STIcluster_MR.STI + rremove("legend") + stat_compare_means(method="t.test", ref.group = 1, 
                                                              label = "p.signif", hide.ns = T)
STIcluster_MR.STI

STIcluster_LRno.STI <- ggerrorplot(growth_cluster3, y = "LRno.STI", x = "clusters", fill="clusters", 
                                   color="clusters", desc_stat = "mean_sd", add = "jitter", 
                                   add.params = list(color = "darkgray"), xlab="", 
                                   ylab="Fraction of Control (LR #)", title = "Lateral Root # STI") 
STIcluster_LRno.STI <- STIcluster_LRno.STI + rremove("legend") + stat_compare_means(method="t.test", ref.group = 1, 
                                                              label = "p.signif", hide.ns = T)
STIcluster_LRno.STI

STIcluster_aLRL.STI <- ggerrorplot(growth_cluster3, y = "aLRL.STI", x = "clusters", fill="clusters", 
                                   color="clusters", desc_stat = "mean_sd", add = "jitter", 
                                   add.params = list(color = "darkgray"), xlab="", 
                                   ylab="Fraction of Control (avg. Lateral Root Growth)", 
                                   title = " avg Lateral Root Growth STI") 
STIcluster_aLRL.STI <- STIcluster_aLRL.STI + rremove("legend") + stat_compare_means(method="t.test", ref.group = 1, 
                                                              label = "p.signif", hide.ns = T)
STIcluster_aLRL.STI

Let’s put these into one figure and think about it in another session:

pdf("Fig.STI_based_clusters_STI_trait_comparison.pdf", height = 15, width = 10)
plot_grid(STIcluster_MR.STI, STIcluster_LRno.STI, STIcluster_aLRL.STI, ncol=1, labels="AUTO")
dev.off()
null device 
          1 

I m still wondering how the correlations between the traits would look if we would color it per cluster now:

growth_cluster3$clusters <- as.factor(growth_cluster3$clusters)

STI_aLRL_vs_LRno_clust <- ggscatter(growth_cluster3, x = "aLRL.STI", y = "LRno.STI", color = "clusters", size = 0.3, 
                            rug = TRUE, ellipse = TRUE, palette = "jco") + stat_cor(method = "pearson")
STI_aLRL_vs_LRno_clust

STI_aLRL_vs_MR_clust <- ggscatter(growth_cluster3, x = "aLRL.STI", y = "MR.STI", color = "clusters", size = 0.3, 
                            rug = TRUE, ellipse = TRUE, palette = "jco") + stat_cor(method = "pearson")
STI_aLRL_vs_MR_clust

STI_LRno_vs_MR_clust <- ggscatter(growth_cluster3, x = "LRno.STI", y = "MR.STI", color = "clusters", size = 0.3, 
                            rug = TRUE, ellipse = TRUE, palette = "jco") + stat_cor(method = "pearson")
STI_LRno_vs_MR_clust

I wonder if we could visualize accessions that belong to individual clusters in the continuous graphs with average per accession.

Let’s load the STI_cluster table:

cluster01 <- read.table("STI_clusters_better.txt", header = T)
head(cluster01)

now let’s fuse it with the MR_sum dataset that we used previously for timeseries graphs:

head(MR_sum)
MR_sum2 <- MR_sum
MR_sum2$genotype <- as.numeric(as.character(MR_sum2$genotype))
MR_cluster <- merge(MR_sum2, cluster01, by="genotype", all=T)
head(MR_cluster)
MR_cluster$cluster <- as.factor(MR_cluster$cluster)

Cool - now let’s see how the TRS graph looks like when we colour per cluster:

ggplotly(TRS_clust_lgraph)
`group_by_()` is deprecated as of dplyr 0.7.0.
Please use `group_by()` instead.
See vignette('programming') for more help
This warning is displayed once every 8 hours.
Call `lifecycle::last_warnings()` to see where this warning was generated.
STIcluster_MR.C <- ggerrorplot(growth_cluster3, y = "MR.delta.Control", x = "clusters", fill="clusters", 
                                   color="clusters", desc_stat = "mean_sd", add = "jitter", 
                                   add.params = list(color = "darkgray"), xlab="Clusters based on STI", 
                                   ylab="Main Root Growth (cm / day)", title = "Control") 
STIcluster_MR.C <- STIcluster_MR.C + rremove("legend") + stat_compare_means(method="t.test", ref.group = 1, 
                                                              label = "p.signif", hide.ns = T)
STIcluster_MR.C

STIcluster_MR.S <- ggerrorplot(growth_cluster3, y = "MR.delta.Salt", x = "clusters", fill="clusters", 
                                   color="clusters", desc_stat = "mean_sd", add = "jitter", 
                                   add.params = list(color = "darkgray"), xlab="Clusters based on STI", 
                                   ylab="Main Root Growth (cm / day)", title = "Salt") 
STIcluster_MR.S <- STIcluster_MR.S + rremove("legend") + stat_compare_means(method="t.test", ref.group = 1, 
                                                              label = "p.signif", hide.ns = T)
STIcluster_MR.S

STIcluster_aLR.C <- ggerrorplot(growth_cluster3, y = "aLRL.delta.Control", x = "clusters", fill="clusters", 
                                   color="clusters", desc_stat = "mean_sd", add = "jitter", 
                                   add.params = list(color = "darkgray"), xlab="Clusters based on STI", 
                                   ylab="avg Lateral Root Growth (cm / day)", title = "Control") 
STIcluster_aLR.C <- STIcluster_aLR.C + rremove("legend") + stat_compare_means(method="t.test", ref.group = 1, 
                                                              label = "p.signif", hide.ns = T)
STIcluster_aLR.C

STIcluster_aLR.S <- ggerrorplot(growth_cluster3, y = "aLRL.delta.Salt", x = "clusters", fill="clusters", 
                                   color="clusters", desc_stat = "mean_sd", add = "jitter", 
                                   add.params = list(color = "darkgray"), xlab="Clusters based on STI", 
                                   ylab="avg Lateral Root Growth (cm / day)", title = "Salt") 
STIcluster_aLR.S <- STIcluster_aLR.S + rremove("legend") + stat_compare_means(method="t.test", ref.group = 1, 
                                                              label = "p.signif", hide.ns = T)
STIcluster_aLR.S

STIcluster_LRno.C <- ggerrorplot(growth_cluster3, y = "LRno.delta.Control", x = "clusters", fill="clusters", id="genotype",  
                                   color="clusters", desc_stat = "mean_sd", add = "jitter", 
                                   add.params = list(color = "darkgray"), xlab="Clusters based on STI", 
                                   ylab="Lateral Root Increase (# LR / day)", title = "Control") 
STIcluster_LRno.C <- STIcluster_LRno.C + rremove("legend") + stat_compare_means(method="t.test", ref.group = 1, 
                                                              label = "p.signif", hide.ns = T)
STIcluster_LRno.C

library(plotly)
ggplotly(STIcluster_LRno.C)
STIcluster_LRno.S <- ggerrorplot(growth_cluster3, y = "LRno.delta.Salt", x = "clusters", fill="clusters", 
                                   color="clusters", desc_stat = "mean_sd", add = "jitter", 
                                   add.params = list(color = "darkgray"), xlab="Clusters based on STI", 
                                   ylab="Lateral Root Increase (# LR / day)", title = "Salt") 
STIcluster_LRno.S <- STIcluster_LRno.S + rremove("legend") + stat_compare_means(method="t.test", ref.group = 1, 
                                                              label = "p.signif", hide.ns = T)
STIcluster_LRno.S

Let’s have a look and select accessions:

tomato$genotype
 [1] " 002" " 008" " 012" " 013" " 063" " 075" " 084" " 086" " 087" " 088" " 091" " 092" " 094" " 095" " 096" " 101"
[17] " 104" " 105" " 106" " 139" " 144" " 146" " 147" " 165" " 167" " 168" " 169" " 171" " 173" " 192" " 197" " 230"
[33] " 241" " 245" " 248" " 250" " 253" " 255" " 280" " 292"

that’s of course based on the mean - lets have a look at the most interesting accessions tho:

interesting <- subset(all_MR3, all_MR3$genotype == " 002")
interesting

M002_lgraph <- ggplot(data=interesting, aes(x= DAS, y=TRS, group = root_name, color = cond)) 
M002_lgraph <- M002_lgraph +geom_line(alpha = 0.1) 
M002_lgraph <- M002_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)
M002_lgraph <- M002_lgraph + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
M002_lgraph <- M002_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
M002_lgraph <- M002_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("M002")
M002_lgraph <- M002_lgraph + ylab("Total Root Size (cm)") + xlab("Days After Stress") + theme(legend.position='none')
M002_lgraph

interesting <- subset(all_MR3, all_MR3$genotype == " 248")
interesting

M248_lgraph <- ggplot(data=interesting, aes(x= DAS, y=TRS, group = root_name, color = cond)) 
M248_lgraph <- M248_lgraph +geom_line(alpha = 0.1) 
M248_lgraph <- M248_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)
M248_lgraph <- M248_lgraph + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
M248_lgraph <- M248_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
M248_lgraph <- M248_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("M248")
M248_lgraph <- M248_lgraph + ylab("Total Root Size (cm)") + xlab("Days After Stress") + theme(legend.position='none')
M248_lgraph

Pareto and RSA

OK - so now let’s get to the actual paretho calculations made by Arjun.

getwd()
[1] "/Users/magdalena/Dropbox/DataAndAnalysis/Tomato/PimpiBIG csv raw files"
Pareto_01 <- read.csv("/Users/magdalena/Dropbox/DataAndAnalysis/Tomato/PimpiBIG csv raw files/Arjun_Paretho/arbor_stats.csv")
Pareto_01
Pareto_02 <- read.csv("/Users/magdalena/Dropbox/DataAndAnalysis/Tomato/PimpiBIG csv raw files/Arjun_Paretho/scaling_distances.csv")
Pareto_02
head(all_MR3)
meta <- read.csv("/Users/magdalena/Dropbox/DataAndAnalysis/Tomato/PimpiBIG csv raw files/Arjun_Paretho/metadata.csv")
meta

Cool - let’s try to fuse it all together:

dim(Pareto_01)
[1] 4219    3
dim(Pareto_02)
[1] 4218    5
dim(meta)
[1] 5559    7
dim(all_MR3)
[1] 5507   64

ok - so for some reason we do have less paretho calculated than actually plants, but that’s ok at this point.

Let’s first fuse two paretho files:

Then add meta-data

unique(Pareto_all$arbor.name)
   [1] "001_1_C_day2" "001_1_C_day3" "001_1_C_day4" "001_1_C_day5" "001_1_S_day2" "001_1_S_day3" "001_1_S_day4"
   [8] "001_1_S_day5" "001_2_C_day2" "001_2_C_day3" "001_2_C_day4" "001_2_C_day5" "001_2_S_day2" "001_2_S_day3"
  [15] "001_2_S_day4" "001_2_S_day5" "001_3_C_day1" "001_3_C_day2" "001_3_C_day3" "001_3_C_day4" "001_3_C_day5"
  [22] "001_3_S_day2" "001_3_S_day3" "001_3_S_day4" "001_3_S_day5" "001_4_C_day2" "001_4_C_day3" "001_4_C_day4"
  [29] "001_4_C_day5" "001_4_S_day2" "001_4_S_day3" "001_4_S_day4" "001_4_S_day5" "002_1_C_day2" "002_1_C_day3"
  [36] "002_1_C_day4" "002_1_C_day5" "002_1_S_day1" "002_1_S_day2" "002_1_S_day3" "002_1_S_day4" "002_1_S_day5"
  [43] "002_2_C_day2" "002_2_C_day3" "002_2_C_day4" "002_2_C_day5" "002_2_S_day2" "002_2_S_day3" "002_2_S_day4"
  [50] "002_2_S_day5" "002_3_C_day2" "002_3_C_day3" "002_3_C_day4" "002_3_C_day5" "002_3_S_day2" "002_3_S_day3"
  [57] "002_3_S_day4" "002_3_S_day5" "002_4_S_day2" "002_4_S_day3" "002_4_S_day4" "002_4_S_day5" "003_1_C_day2"
  [64] "003_1_C_day3" "003_1_C_day4" "003_1_C_day5" "003_1_S_day3" "003_1_S_day4" "003_1_S_day5" "003_2_S_day2"
  [71] "003_2_S_day3" "003_2_S_day4" "003_2_S_day5" "003_3_C_day2" "003_3_C_day3" "003_3_C_day4" "003_3_C_day5"
  [78] "003_3_S_day2" "003_3_S_day3" "003_3_S_day4" "003_3_S_day5" "005_1_S_day2" "005_1_S_day3" "005_1_S_day4"
  [85] "005_1_S_day5" "005_2_C_day2" "005_2_C_day3" "005_2_C_day4" "005_2_C_day5" "005_2_S_day4" "005_2_S_day5"
  [92] "005_3_C_day2" "005_3_C_day3" "005_3_C_day4" "005_3_C_day5" "005_3_S_day4" "005_3_S_day5" "005_4_C_day2"
  [99] "005_4_C_day3" "005_4_C_day4" "005_4_C_day5" "005_4_S_day3" "005_4_S_day4" "005_4_S_day5" "006_1_C_day2"
 [106] "006_1_C_day3" "006_1_C_day4" "006_1_C_day5" "006_1_S_day3" "006_1_S_day4" "006_1_S_day5" "006_2_C_day2"
 [113] "006_2_C_day3" "006_2_C_day4" "006_2_C_day5" "006_2_S_day4" "006_2_S_day5" "006_3_C_day2" "006_3_C_day3"
 [120] "006_3_C_day4" "006_3_C_day5" "006_3_S_day3" "006_3_S_day4" "006_3_S_day5" "007_1_C_day2" "007_1_C_day3"
 [127] "007_1_C_day4" "007_1_C_day5" "007_1_S_day2" "007_1_S_day3" "007_1_S_day4" "007_1_S_day5" "007_2_C_day2"
 [134] "007_2_C_day3" "007_2_C_day4" "007_2_C_day5" "007_2_S_day2" "007_2_S_day3" "007_2_S_day4" "007_2_S_day5"
 [141] "007_3_C_day2" "007_3_C_day3" "007_3_C_day4" "007_3_C_day5" "007_3_S_day2" "007_3_S_day3" "007_3_S_day4"
 [148] "007_3_S_day5" "008_1_C_day2" "008_1_C_day3" "008_1_C_day4" "008_1_C_day5" "008_1_S_day2" "008_1_S_day3"
 [155] "008_1_S_day4" "008_1_S_day5" "008_2_C_day2" "008_2_C_day3" "008_2_C_day4" "008_2_C_day5" "008_2_S_day2"
 [162] "008_2_S_day3" "008_2_S_day4" "008_2_S_day5" "008_3_C_day1" "008_3_C_day2" "008_3_C_day3" "008_3_C_day4"
 [169] "008_3_C_day5" "008_3_S_day2" "008_3_S_day3" "008_3_S_day4" "008_3_S_day5" "008_4_C_day2" "008_4_C_day3"
 [176] "008_4_C_day4" "008_4_C_day5" "008_4_S_day2" "008_4_S_day3" "008_4_S_day4" "008_4_S_day5" "009_1_C_day1"
 [183] "009_1_C_day2" "009_1_C_day3" "009_1_C_day4" "009_1_C_day5" "009_1_S_day2" "009_1_S_day3" "009_1_S_day4"
 [190] "009_1_S_day5" "009_2_C_day2" "009_2_C_day3" "009_2_C_day4" "009_2_C_day5" "009_2_S_day2" "009_2_S_day3"
 [197] "009_2_S_day4" "009_2_S_day5" "009_3_C_day2" "009_3_C_day3" "009_3_C_day4" "009_3_C_day5" "009_3_S_day2"
 [204] "009_3_S_day3" "009_3_S_day4" "009_3_S_day5" "009_4_C_day2" "009_4_C_day3" "009_4_C_day4" "009_4_C_day5"
 [211] "009_4_S_day1" "009_4_S_day2" "009_4_S_day3" "009_4_S_day4" "009_4_S_day5" "010_1_C_day4" "010_1_C_day5"
 [218] "010_2_C_day3" "010_2_C_day4" "010_2_C_day5" "010_3_C_day4" "010_3_C_day5" "010_3_S_day1" "010_3_S_day5"
 [225] "011_1_C_day2" "011_1_C_day3" "011_1_C_day4" "011_1_C_day5" "011_1_S_day3" "011_1_S_day4" "011_1_S_day5"
 [232] "011_2_C_day2" "011_2_C_day3" "011_2_C_day4" "011_2_C_day5" "011_2_S_day2" "011_2_S_day3" "011_2_S_day4"
 [239] "011_2_S_day5" "011_3_C_day2" "011_3_C_day3" "011_3_C_day4" "011_3_C_day5" "011_3_S_day2" "011_3_S_day3"
 [246] "011_3_S_day4" "011_3_S_day5" "011_4_C_day1" "011_4_C_day2" "011_4_C_day3" "011_4_C_day4" "011_4_C_day5"
 [253] "011_4_S_day4" "011_4_S_day5" "012_1_C_day2" "012_1_C_day3" "012_1_C_day4" "012_1_C_day5" "012_1_S_day1"
 [260] "012_1_S_day2" "012_1_S_day3" "012_1_S_day4" "012_1_S_day5" "012_2_C_day2" "012_2_C_day3" "012_2_C_day4"
 [267] "012_2_C_day5" "012_2_S_day2" "012_2_S_day3" "012_2_S_day4" "012_2_S_day5" "012_3_C_day2" "012_3_C_day3"
 [274] "012_3_C_day4" "012_3_C_day5" "012_3_S_day1" "012_3_S_day2" "012_3_S_day3" "012_3_S_day4" "012_3_S_day5"
 [281] "012_4_C_day2" "012_4_C_day3" "012_4_C_day4" "012_4_C_day5" "012_4_S_day2" "012_4_S_day4" "012_4_S_day5"
 [288] "013_1_C_day2" "013_1_C_day3" "013_1_C_day4" "013_1_C_day5" "013_1_S_day2" "013_1_S_day3" "013_1_S_day4"
 [295] "013_1_S_day5" "013_2_C_day1" "013_2_C_day2" "013_2_C_day3" "013_2_C_day4" "013_2_C_day5" "013_2_S_day2"
 [302] "013_2_S_day3" "013_2_S_day4" "013_2_S_day5" "013_3_C_day1" "013_3_C_day2" "013_3_C_day3" "013_3_C_day4"
 [309] "013_3_C_day5" "013_3_S_day2" "013_3_S_day3" "013_3_S_day4" "013_3_S_day5" "022_4_C_day2" "022_4_C_day3"
 [316] "022_4_C_day4" "022_4_C_day5" "028_1_C_day2" "028_1_C_day3" "028_1_C_day4" "028_1_C_day5" "028_1_S_day2"
 [323] "028_1_S_day3" "028_1_S_day4" "028_1_S_day5" "028_2_C_day1" "028_2_C_day2" "028_2_C_day3" "028_2_C_day4"
 [330] "028_2_C_day5" "028_2_S_day2" "028_2_S_day3" "028_2_S_day4" "028_3_C_day2" "028_3_C_day3" "028_3_C_day4"
 [337] "028_3_C_day5" "028_3_S_day2" "028_3_S_day3" "028_3_S_day4" "028_3_S_day5" "028_4_C_day2" "028_4_C_day3"
 [344] "028_4_C_day4" "028_4_C_day5" "028_4_S_day3" "028_4_S_day4" "028_4_S_day5" "029_1_C_day2" "029_1_C_day3"
 [351] "029_1_C_day4" "029_1_C_day5" "029_1_S_day3" "029_1_S_day4" "029_1_S_day5" "029_2_C_day2" "029_2_C_day3"
 [358] "029_2_C_day4" "029_2_C_day5" "029_2_S_day4" "029_2_S_day5" "029_3_C_day2" "029_3_C_day3" "029_3_C_day4"
 [365] "029_3_C_day5" "029_3_S_day2" "029_3_S_day3" "029_3_S_day4" "029_3_S_day5" "029_4_C_day2" "029_4_C_day3"
 [372] "029_4_C_day4" "029_4_C_day5" "029_4_S_day2" "029_4_S_day3" "029_4_S_day4" "029_4_S_day5" "030_1_C_day1"
 [379] "030_1_C_day2" "030_1_C_day3" "030_1_C_day4" "030_1_C_day5" "030_1_S_day2" "030_1_S_day3" "030_1_S_day4"
 [386] "030_1_S_day5" "030_2_C_day2" "030_2_C_day3" "030_2_C_day4" "030_2_C_day5" "030_2_S_day2" "030_2_S_day3"
 [393] "030_2_S_day4" "030_2_S_day5" "030_3_C_day2" "030_3_C_day3" "030_3_C_day4" "030_3_C_day5" "030_3_S_day2"
 [400] "030_3_S_day3" "030_3_S_day4" "030_3_S_day5" "031_1_C_day2" "031_1_C_day3" "031_1_C_day4" "031_1_C_day5"
 [407] "031_1_S_day2" "031_1_S_day3" "031_1_S_day4" "031_1_S_day5" "031_2_C_day2" "031_2_C_day3" "031_2_C_day4"
 [414] "031_2_C_day5" "031_2_S_day3" "031_2_S_day4" "031_2_S_day5" "031_3_C_day2" "031_3_C_day3" "031_3_C_day4"
 [421] "031_3_C_day5" "031_3_S_day3" "031_3_S_day4" "031_3_S_day5" "031_4_C_day2" "031_4_C_day3" "031_4_C_day4"
 [428] "031_4_C_day5" "031_4_S_day2" "031_4_S_day3" "031_4_S_day4" "031_4_S_day5" "032_1_C_day2" "032_1_C_day3"
 [435] "032_1_C_day4" "032_1_C_day5" "032_1_S_day4" "032_1_S_day5" "032_2_C_day2" "032_2_C_day3" "032_2_C_day4"
 [442] "032_2_C_day5" "032_2_S_day2" "032_2_S_day3" "032_2_S_day4" "032_2_S_day5" "032_3_C_day2" "032_3_C_day3"
 [449] "032_3_C_day4" "032_3_C_day5" "032_3_S_day2" "032_3_S_day3" "032_3_S_day4" "032_3_S_day5" "032_4_C_day2"
 [456] "032_4_C_day3" "032_4_C_day4" "032_4_C_day5" "032_4_S_day2" "032_4_S_day3" "032_4_S_day4" "032_4_S_day5"
 [463] "033_1_C_day2" "033_1_C_day3" "033_1_C_day4" "033_1_C_day5" "033_1_S_day4" "033_1_S_day5" "033_2_C_day2"
 [470] "033_2_C_day3" "033_2_C_day4" "033_2_C_day5" "033_2_S_day4" "033_2_S_day5" "033_3_C_day3" "033_3_C_day4"
 [477] "033_3_C_day5" "033_3_S_day4" "033_3_S_day5" "034_1_C_day2" "034_1_C_day3" "034_1_C_day4" "034_1_C_day5"
 [484] "034_1_S_day4" "034_1_S_day5" "034_2_C_day2" "034_2_C_day3" "034_2_C_day4" "034_2_C_day5" "034_2_S_day5"
 [491] "034_3_C_day2" "034_3_C_day3" "034_3_C_day4" "034_3_C_day5" "034_3_S_day5" "035_1_C_day2" "035_1_C_day3"
 [498] "035_1_C_day4" "035_1_C_day5" "035_1_S_day1" "035_1_S_day2" "035_1_S_day3" "035_1_S_day4" "035_1_S_day5"
 [505] "035_2_C_day2" "035_2_C_day3" "035_2_C_day4" "035_2_C_day5" "035_2_S_day2" "035_2_S_day3" "035_2_S_day4"
 [512] "035_2_S_day5" "035_3_C_day2" "035_3_C_day3" "035_3_C_day4" "035_3_C_day5" "035_3_S_day3" "035_3_S_day4"
 [519] "035_3_S_day5" "035_4_C_day2" "035_4_C_day3" "035_4_C_day4" "035_4_C_day5" "035_4_S_day2" "035_4_S_day3"
 [526] "035_4_S_day4" "035_4_S_day5" "036_1_C_day3" "036_1_C_day4" "036_1_C_day5" "036_1_S_day3" "036_1_S_day4"
 [533] "036_1_S_day5" "036_2_C_day2" "036_2_C_day3" "036_2_C_day4" "036_2_C_day5" "036_2_S_day4" "036_2_S_day5"
 [540] "037_1_C_day3" "037_1_C_day4" "037_1_C_day5" "037_1_S_day4" "037_1_S_day5" "038_1_C_day2" "038_1_C_day3"
 [547] "038_1_C_day4" "038_1_C_day5" "038_1_S_day2" "038_1_S_day3" "038_1_S_day4" "038_1_S_day5" "038_2_C_day2"
 [554] "038_2_C_day3" "038_2_C_day4" "038_2_C_day5" "038_2_S_day1" "038_2_S_day2" "038_2_S_day3" "038_2_S_day4"
 [561] "038_2_S_day5" "038_3_C_day1" "038_3_C_day2" "038_3_C_day3" "038_3_C_day4" "038_3_C_day5" "038_3_S_day2"
 [568] "038_3_S_day3" "038_3_S_day4" "038_3_S_day5" "038_4_C_day1" "038_4_C_day2" "038_4_C_day3" "038_4_C_day4"
 [575] "038_4_C_day5" "038_4_S_day2" "038_4_S_day3" "038_4_S_day4" "038_4_S_day5" "040_1_C_day2" "040_1_C_day3"
 [582] "040_1_C_day4" "040_1_C_day5" "040_1_S_day3" "040_1_S_day4" "040_1_S_day5" "040_2_C_day2" "040_2_C_day3"
 [589] "040_2_C_day4" "040_2_C_day5" "040_2_S_day2" "040_2_S_day3" "040_2_S_day4" "040_2_S_day5" "040_3_C_day2"
 [596] "040_3_C_day3" "040_3_C_day4" "040_3_C_day5" "040_3_S_day2" "040_3_S_day3" "040_3_S_day4" "040_3_S_day5"
 [603] "040_4_C_day2" "040_4_C_day3" "040_4_C_day4" "040_4_C_day5" "040_4_S_day2" "040_4_S_day3" "040_4_S_day4"
 [610] "040_4_S_day5" "055_1_C_day2" "055_1_C_day3" "055_1_C_day4" "055_1_C_day5" "055_1_S_day2" "055_1_S_day3"
 [617] "055_1_S_day4" "055_1_S_day5" "055_2_C_day2" "055_2_C_day3" "055_2_C_day4" "055_2_C_day5" "055_2_S_day2"
 [624] "055_2_S_day3" "055_2_S_day4" "055_2_S_day5" "055_3_C_day2" "055_3_C_day3" "055_3_C_day4" "055_3_C_day5"
 [631] "055_3_S_day2" "055_3_S_day3" "055_3_S_day4" "055_3_S_day5" "056_1_C_day2" "056_1_C_day3" "056_1_C_day4"
 [638] "056_1_C_day5" "056_1_S_day4" "056_1_S_day5" "056_2_C_day2" "056_2_C_day3" "056_2_C_day4" "056_2_C_day5"
 [645] "056_2_S_day1" "056_2_S_day2" "056_2_S_day3" "056_2_S_day4" "056_2_S_day5" "056_3_C_day1" "056_3_C_day2"
 [652] "056_3_C_day3" "056_3_C_day4" "056_3_C_day5" "056_3_S_day2" "056_3_S_day3" "056_3_S_day4" "056_3_S_day5"
 [659] "057_1_C_day2" "057_1_C_day3" "057_1_C_day4" "057_1_C_day5" "057_1_S_day2" "057_1_S_day3" "057_1_S_day4"
 [666] "057_1_S_day5" "057_2_C_day2" "057_2_C_day3" "057_2_C_day4" "057_2_C_day5" "057_2_S_day1" "057_2_S_day2"
 [673] "057_2_S_day3" "057_2_S_day4" "057_2_S_day5" "057_3_C_day2" "057_3_C_day3" "057_3_C_day4" "057_3_C_day5"
 [680] "057_3_S_day2" "057_3_S_day3" "057_3_S_day4" "057_3_S_day5" "057_4_C_day2" "057_4_C_day3" "057_4_C_day4"
 [687] "057_4_C_day5" "057_4_S_day2" "057_4_S_day3" "057_4_S_day4" "057_4_S_day5" "058_1_C_day2" "058_1_C_day3"
 [694] "058_1_C_day4" "058_1_C_day5" "058_2_C_day2" "058_2_C_day3" "058_2_C_day4" "058_2_C_day5" "058_3_C_day2"
 [701] "058_3_C_day3" "058_3_C_day4" "058_3_C_day5" "058_4_C_day2" "058_4_C_day3" "058_4_C_day4" "058_4_C_day5"
 [708] "059_1_C_day1" "059_1_C_day2" "059_1_C_day3" "059_1_S_day2" "059_1_S_day3" "059_1_S_day4" "059_1_S_day5"
 [715] "059_2_C_day2" "059_2_C_day3" "059_2_C_day4" "059_2_C_day5" "059_2_S_day1" "059_2_S_day3" "059_2_S_day4"
 [722] "059_2_S_day5" "059_3_C_day2" "059_3_C_day3" "059_3_C_day4" "059_3_C_day5" "059_3_S_day4" "059_3_S_day5"
 [729] "059_4_C_day2" "059_4_C_day3" "059_4_C_day4" "059_4_C_day5" "059_4_S_day2" "059_4_S_day3" "059_4_S_day4"
 [736] "059_4_S_day5" "060_1_C_day2" "060_1_C_day3" "060_1_C_day4" "060_1_C_day5" "060_1_S_day4" "060_1_S_day5"
 [743] "060_2_C_day2" "060_2_C_day3" "060_2_C_day4" "060_2_C_day5" "060_2_S_day2" "060_2_S_day3" "060_2_S_day4"
 [750] "060_2_S_day5" "060_3_C_day1" "060_3_C_day2" "060_3_C_day3" "060_3_C_day4" "060_3_C_day5" "060_3_S_day2"
 [757] "060_3_S_day3" "060_3_S_day4" "060_3_S_day5" "061_1_C_day1" "061_1_C_day2" "061_1_C_day3" "061_1_C_day4"
 [764] "061_1_C_day5" "061_1_S_day4" "061_1_S_day5" "061_2_C_day2" "061_2_C_day3" "061_2_C_day4" "061_2_C_day5"
 [771] "061_2_S_day4" "061_2_S_day5" "061_3_C_day2" "061_3_C_day3" "061_3_C_day4" "061_3_C_day5" "061_3_S_day2"
 [778] "061_3_S_day3" "061_3_S_day4" "061_3_S_day5" "062_1_C_day2" "062_1_C_day3" "062_1_C_day4" "062_1_C_day5"
 [785] "062_2_S_day3" "062_2_S_day4" "062_2_S_day5" "063_1_C_day1" "063_1_C_day2" "063_1_C_day3" "063_1_C_day4"
 [792] "063_1_C_day5" "063_1_S_day2" "063_1_S_day3" "063_1_S_day4" "063_1_S_day5" "064_1_C_day1" "064_1_C_day2"
 [799] "064_1_C_day3" "064_1_C_day4" "064_1_C_day5" "064_1_S_day3" "064_1_S_day4" "064_1_S_day5" "064_2_C_day3"
 [806] "064_2_C_day4" "064_2_C_day5" "064_2_S_day5" "064_3_C_day2" "064_3_C_day3" "064_3_C_day5" "064_3_S_day2"
 [813] "064_3_S_day3" "064_3_S_day4" "064_3_S_day5" "065_1_C_day1" "065_1_C_day2" "065_1_C_day3" "065_1_C_day4"
 [820] "065_1_C_day5" "065_1_S_day4" "065_1_S_day5" "065_2_C_day2" "065_2_C_day3" "065_2_C_day4" "065_2_C_day5"
 [827] "065_2_S_day2" "065_2_S_day3" "065_2_S_day4" "065_2_S_day5" "065_3_C_day2" "065_3_C_day3" "065_3_C_day4"
 [834] "065_3_C_day5" "065_3_S_day1" "065_3_S_day2" "065_3_S_day3" "065_3_S_day4" "065_3_S_day5" "066_1_C_day2"
 [841] "066_1_C_day3" "066_1_C_day4" "066_1_C_day5" "066_1_S_day4" "066_1_S_day5" "066_2_C_day2" "066_2_C_day3"
 [848] "066_2_C_day4" "066_2_C_day5" "066_2_S_day4" "066_2_S_day5" "074_1_C_day2" "074_1_C_day3" "074_1_C_day4"
 [855] "074_1_C_day5" "074_1_S_day2" "074_1_S_day3" "074_1_S_day4" "074_1_S_day5" "074_2_C_day2" "074_2_C_day3"
 [862] "074_2_C_day4" "074_2_C_day5" "074_2_S_day2" "074_2_S_day3" "074_2_S_day4" "074_2_S_day5" "074_3_C_day2"
 [869] "074_3_C_day3" "074_3_C_day4" "074_3_C_day5" "074_3_S_day2" "074_3_S_day3" "074_3_S_day4" "074_3_S_day5"
 [876] "074_4_C_day2" "074_4_C_day3" "074_4_C_day4" "074_4_C_day5" "074_4_S_day2" "074_4_S_day3" "074_4_S_day4"
 [883] "074_4_S_day5" "075_1_C_day2" "075_1_C_day3" "075_1_C_day4" "075_1_C_day5" "075_1_S_day2" "075_1_S_day3"
 [890] "075_1_S_day4" "075_1_S_day5" "075_2_C_day2" "075_2_C_day3" "075_2_C_day4" "075_2_C_day5" "075_2_S_day1"
 [897] "075_2_S_day2" "075_2_S_day3" "075_2_S_day4" "075_2_S_day5" "075_3_C_day2" "075_3_C_day3" "075_3_C_day4"
 [904] "075_3_C_day5" "075_3_S_day2" "075_3_S_day3" "075_3_S_day4" "075_3_S_day5" "076_1_C_day2" "076_1_C_day3"
 [911] "076_1_C_day4" "076_1_C_day5" "076_1_S_day1" "076_1_S_day2" "076_1_S_day3" "076_1_S_day4" "076_1_S_day5"
 [918] "076_2_C_day2" "076_2_C_day3" "076_2_C_day4" "076_2_C_day5" "076_2_S_day1" "076_2_S_day2" "076_2_S_day3"
 [925] "076_2_S_day4" "076_2_S_day5" "076_3_C_day2" "076_3_C_day3" "076_3_C_day4" "076_3_C_day5" "076_3_S_day1"
 [932] "076_3_S_day2" "076_3_S_day3" "076_3_S_day4" "076_3_S_day5" "076_4_C_day1" "076_4_C_day2" "076_4_C_day3"
 [939] "076_4_C_day4" "076_4_C_day5" "076_4_S_day4" "076_4_S_day5" "078_1_C_day2" "078_1_C_day3" "078_1_C_day4"
 [946] "078_1_C_day5" "078_1_S_day2" "078_1_S_day3" "078_1_S_day4" "078_1_S_day5" "078_2_C_day3" "078_2_C_day4"
 [953] "078_2_C_day5" "078_3_S_day3" "078_3_S_day4" "078_3_S_day5" "079_1_C_day2" "079_1_C_day3" "079_1_C_day4"
 [960] "079_1_C_day5" "079_1_S_day3" "079_1_S_day4" "079_1_S_day5" "079_2_C_day2" "079_2_C_day3" "079_2_C_day4"
 [967] "079_2_C_day5" "079_2_S_day3" "079_2_S_day4" "079_2_S_day5" "079_3_C_day2" "079_3_C_day3" "079_3_C_day4"
 [974] "079_3_C_day5" "079_3_S_day2" "079_3_S_day3" "079_3_S_day4" "079_3_S_day5" "079_4_C_day2" "079_4_C_day3"
 [981] "079_4_C_day4" "079_4_C_day5" "079_4_S_day2" "079_4_S_day3" "079_4_S_day4" "079_4_S_day5" "080_1_C_day2"
 [988] "080_1_C_day3" "080_1_C_day4" "080_1_C_day5" "080_1_S_day3" "080_1_S_day4" "080_1_S_day5" "080_2_C_day2"
 [995] "080_2_C_day3" "080_2_C_day4" "080_2_C_day5" "080_2_S_day3" "080_2_S_day4" "080_2_S_day5"
 [ reached getOption("max.print") -- omitted 3218 entries ]
unique(meta$arbor.name)
   [1] "103_4_S_day5"  "031_3_S_day5"  "055_2_S_day5"  "098_1_S_day5"  "101_1_S_day5"  "059_4_C_day5"  "034_1_C_day5" 
   [8] "030_2_S_day5"  "002_1_C_day5"  "001_3_C_day5"  "076_1_C_day5"  "102_4_C_day5"  "104_3_S_day5"  "080_2_S_day5" 
  [15] "080_1_S_day5"  "005_3_S_day5"  "081_1_C_day5"  "096_1_C_day5"  "101_2_C_day5"  "028_4_C_day5"  "058_4_C_day5" 
  [22] "009_2_C_day5"  "038_3_C_day5"  "079_4_C_day5"  "080_4_S_day5"  "040_1_C_day5"  "035_4_C_day5"  "040_1_S_day5" 
  [29] "094_3_C_day5"  "074_4_C_day5"  "010_2_C_day5"  "103_1_S_day5"  "032_4_S_day5"  "103_1_C_day5"  "102_2_S_day5" 
  [36] "010_1_S_day5"  "022_4_C_day5"  "003_3_S_day5"  "105_3_C_day5"  "056_2_S_day5"  "009_3_S_day5"  "095_1_S_day5" 
  [43] "002_2_S_day5"  "011_4_S_day5"  "106_1_S_day5"  "040_3_S_day5"  "098_3_C_day5"  "001_4_S_day5"  "075_2_C_day5" 
  [50] "103_2_S_day5"  "009_2_S_day5"  "028_3_C_day5"  "081_1_S_day5"  "012_1_S_day5"  "033_2_C_day5"  "098_3_S_day5" 
  [57] "079_2_S_day5"  "058_4_S_day5"  "097_1_S_day5"  "013_3_C_day5"  "031_1_S_day5"  "094_2_S_day5"  "013_2_S_day5" 
  [64] "006_3_S_day5"  "007_1_C_day5"  "057_1_S_day5"  "008_1_S_day5"  "076_3_C_day5"  "008_3_C_day5"  "012_3_S_day5" 
  [71] "099_4_C_day5"  "094_3_S_day5"  "057_3_C_day5"  "035_2_S_day5"  "099_1_C_day5"  "029_4_S_day5"  "012_2_S_day5" 
  [78] "030_2_C_day5"  "105_3_S_day5"  "012_4_S_day5"  "007_2_S_day5"  "032_1_C_day5"  "013_1_C_day5"  "038_2_S_day5" 
  [85] "010_3_S_day5"  "078_3_S_day5"  "058_2_S_day5"  "099_1_S_day5"  "001_1_C_day5"  "057_1_C_day5"  "098_4_S_day5" 
  [92] "057_2_S_day5"  "080_1_C_day5"  "006_3_C_day5"  "029_3_S_day5"  "094_2_C_day5"  "056_3_C_day5"  "028_1_S_day5" 
  [99] "095_4_S_day5"  "074_3_C_day5"  "040_2_C_day5"  "105_1_S_day5"  "001_2_S_day5"  "003_3_C_day5"  "075_3_S_day5" 
 [106] "007_2_C_day5"  "031_2_C_day5"  "035_2_C_day5"  "074_4_S_day5"  "059_3_C_day5"  "007_3_C_day5"  "001_2_C_day5" 
 [113] "106_2_C_day5"  "007_1_S_day5"  "104_2_S_day5"  "040_4_C_day5"  "002_1_S_day5"  "005_3_C_day5"  "079_3_S_day5" 
 [120] "103_4_C_day5"  "009_1_C_day5"  "096_2_S_day5"  "032_2_C_day5"  "099_2_S_day5"  "055_2_C_day5"  "057_4_S_day5" 
 [127] "075_3_C_day5"  "028_3_S_day5"  "007_3_S_day5"  "095_4_C_day5"  "081_4_S_day5"  "081_3_C_day5"  "056_3_S_day5" 
 [134] "103_3_S_day5"  "037_1_C_day5"  "059_2_C_day5"  "012_3_C_day5"  "099_3_C_day5"  "038_1_S_day5"  "079_1_C_day5" 
 [141] "038_4_C_day5"  "031_4_C_day5"  "102_3_C_day5"  "006_2_C_day5"  "059_3_S_day5"  "101_2_S_day5"  "057_2_C_day5" 
 [148] "103_3_C_day5"  "104_3_C_day5"  "057_4_C_day5"  "029_3_C_day5"  "105_4_S_day5"  "030_1_S_day5"  "057_3_S_day5" 
 [155] "058_1_C_day5"  "036_2_C_day5"  "030_1_C_day5"  "010_2_S_day5"  "038_2_C_day5"  "011_1_C_day5"  "032_3_S_day5" 
 [162] "035_1_S_day5"  "078_1_C_day5"  "056_2_C_day5"  "029_1_C_day5"  "101_3_S_day5"  "081_2_S_day5"  "055_1_S_day5" 
 [169] "005_2_S_day5"  "034_1_S_day5"  "008_1_C_day5"  "011_3_C_day5"  "055_3_C_day5"  "001_1_S_day5"  "105_4_C_day5" 
 [176] "003_2_S_day5"  "102_4_S_day5"  "031_4_S_day5"  "079_3_C_day5"  "013_2_C_day5"  "059_2_S_day5"  "010_1_C_day5" 
 [183] "008_3_S_day5"  "104_1_S_day5"  "010_3_C_day5"  "011_4_C_day5"  "058_2_C_day5"  "099_4_S_day5"  "075_1_C_day5" 
 [190] "080_2_C_day5"  "009_1_S_day5"  "033_2_S_day5"  "099_2_C_day5"  "038_3_S_day5"  "011_3_S_day5"  "055_3_S_day5" 
 [197] "080_3_S_day5"  "028_1_C_day5"  "035_3_C_day5"  "008_2_S_day5"  "094_1_C_day5"  "056_1_S_day5"  "030_3_C_day5" 
 [204] "035_3_S_day5"  "005_4_C_day5"  "058_3_S_day5"  "038_1_C_day5"  "056_1_C_day5"  "079_4_S_day5"  "031_1_C_day5" 
 [211] "012_2_C_day5"  "095_3_S_day5"  "105_1_C_day5"  "033_3_S_day5"  "097_1_C_day5"  "029_4_C_day5"  "081_3_S_day5" 
 [218] "034_3_C_day5"  "002_2_C_day5"  "074_2_C_day5"  "033_1_C_day5"  "006_1_S_day5"  "079_1_S_day5"  "033_1_S_day5" 
 [225] "035_1_C_day5"  "035_4_S_day5"  "011_2_S_day5"  "029_2_S_day5"  "005_1_S_day5"  "001_4_C_day5"  "028_2_C_day5" 
 [232] "101_3_C_day5"  "013_1_S_day5"  "006_2_S_day5"  "096_2_C_day5"  "040_2_S_day5"  "098_2_C_day5"  "076_4_C_day5" 
 [239] "102_2_C_day5"  "012_1_C_day5"  "001_3_S_day5"  "078_2_S_day5"  "012_4_C_day5"  "002_3_S_day5"  "076_2_S_day5" 
 [246] "032_2_S_day5"  "096_3_S_day5"  "032_1_S_day5"  "101_4_C_day5"  "002_4_S_day5"  "101_4_S_day5"  "059_1_S_day5" 
 [253] "036_1_S_day5"  "079_2_C_day5"  "008_2_C_day5"  "098_4_C_day5"  "095_2_C_day5"  "011_1_S_day5"  "036_1_C_day5" 
 [260] "094_1_S_day5"  "081_4_C_day5"  "034_3_S_day5"  "031_2_S_day5"  "106_1_C_day5"  "036_2_S_day5"  "030_3_S_day5" 
 [267] "080_4_C_day5"  "040_4_S_day5"  "040_3_C_day5"  "076_1_S_day5"  "032_3_C_day5"  "029_2_C_day5"  "101_1_C_day5" 
 [274] "078_2_C_day5"  "105_2_S_day5"  "037_1_S_day5"  "055_1_C_day5"  "003_1_C_day5"  "038_4_S_day5"  "002_3_C_day5" 
 [281] "096_3_C_day5"  "034_2_S_day5"  "102_1_C_day5"  "102_1_S_day5"  "076_4_S_day5"  "032_4_C_day5"  "098_2_S_day5" 
 [288] "104_1_C_day5"  "076_3_S_day5"  "075_2_S_day5"  "058_1_S_day5"  "102_3_S_day5"  "095_2_S_day5"  "099_3_S_day5" 
 [295] "009_4_S_day5"  "104_4_S_day5"  "031_3_C_day5"  "081_2_C_day5"  "006_1_C_day5"  "074_2_S_day5"  "009_3_C_day5" 
 [302] "009_4_C_day5"  "075_1_S_day5"  "028_4_S_day5"  "008_4_C_day5"  "058_3_C_day5"  "029_1_S_day5"  "078_1_S_day5" 
 [309] "103_2_C_day5"  "106_2_S_day5"  "076_2_C_day5"  "095_3_C_day5"  "008_4_S_day5"  "003_1_S_day5"  "074_1_S_day5" 
 [316] "096_1_S_day5"  "104_4_C_day5"  "059_4_S_day5"  "105_2_C_day5"  "013_3_S_day5"  "011_2_C_day5"  "074_3_S_day5" 
 [323] "074_1_C_day5"  "034_2_C_day5"  "095_1_C_day5"  "033_3_C_day5"  "005_2_C_day5"  "104_2_C_day5"  "005_4_S_day5" 
 [330] "028_2_S_day5"  "292_3_S_day2"  "212_1_S_day2"  "307_2_C_day2"  "282_3_C_day2"  "199_2_S_day2"  "278_1_S_day2" 
 [337] "301_1_C_day2"  "287_1_S_day2"  "213_2_C_day2"  "214_1_C_day2"  "286_2_C_day2"  "194_1_S_day2"  "212_1_C_day2" 
 [344] "285_2_S_day2"  "284_2_S_day2"  "285_3_S_day2"  "278_1_C_day2"  "196_2_S_day2"  "201_2_S_day2"  "307_1_S_day2" 
 [351] "279_1_S_day2"  "293_3_S_day2"  "280_1_S_day2"  "194_3_S_day2"  "299_2_C_day2"  "207_1_S_day2"  "298_3_C_day2" 
 [358] "282_1_C_day2"  "285_3_C_day2"  "307_3_C_day2"  "200_1_S_day2"  "211_3_S_day2"  "308_3_C_day2"  "298_3_S_day2" 
 [365] "308_2_C_day2"  "287_1_C_day2"  "301_1_S_day2"  "299_1_C_day2"  "278_3_C_day2"  "283_2_S_day2"  "306_2_S_day2" 
 [372] "280_1_C_day2"  "220_1_C_day2"  "213_2_S_day2"  "287_3_S_day2"  "194_3_C_day2"  "194_1_C_day2"  "282_2_S_day2" 
 [379] "290_3_C_day2"  "196_2_C_day2"  "198_2_C_day2"  "292_2_C_day2"  "299_3_S_day2"  "195_2_S_day2"  "289_2_S_day2" 
 [386] "282_2_C_day2"  "299_1_S_day2"  "300_3_C_day2"  "298_2_C_day2"  "288_3_C_day2"  "307_1_C_day2"  "201_3_C_day2" 
 [393] "291_3_C_day2"  "277_2_S_day2"  "220_1_S_day2"  "2800_3_S_day2" "196_1_S_day2"  "207_2_S_day2"  "278_3_S_day2" 
 [400] "306_3_S_day2"  "306_3_C_day2"  "199_3_C_day2"  "290_1_C_day2"  "299_2_S_day2"  "211_2_S_day2"  "211_2_C_day2" 
 [407] "199_1_C_day2"  "214_1_S_day2"  "277_1_S_day2"  "299_3_C_day2"  "292_3_C_day2"  "207_2_C_day2"  "220_2_S_day2" 
 [414] "214_2_C_day2"  "285_1_S_day2"  "194_2_C_day2"  "278_2_C_day2"  "212_3_S_day2"  "284_1_C_day2"  "211_3_C_day2" 
 [421] "283_3_S_day2"  "286_3_C_day2"  "306_1_S_day2"  "277_2_C_day2"  "279_3_S_day2"  "283_1_S_day2"  "307_3_S_day2" 
 [428] "195_1_C_day2"  "197_2_S_day2"  "288_1_S_day2"  "300_2_S_day2"  "287_2_C_day2"  "301_3_C_day2"  "197_1_S_day2" 
 [435] "198_3_S_day2"  "201_1_C_day2"  "214_2_S_day2"  "189_3_C_day2"  "288_2_C_day2"  "207_3_S_day2"  "213_3_S_day2" 
 [442] "288_1_C_day2"  "306_1_C_day2"  "212_2_C_day2"  "212_3_C_day2"  "199_1_S_day2"  "207_3_C_day2"  "286_2_S_day2" 
 [449] "220_2_C_day2"  "286_1_S_day2"  "201_1_S_day2"  "277_1_C_day2"  "195_3_C_day2"  "293_2_C_day2"  "287_2_S_day2" 
 [456] "213_1_C_day2"  "294_2_C_day2"  "283_2_C_day2"  "292_1_C_day2"  "214_3_C_day2"  "300_1_S_day2"  "298_1_S_day2" 
 [463] "294_3_S_day2"  "291_2_S_day2"  "280_3_C_day2"  "290_2_C_day2"  "197_3_S_day2"  "298_1_C_day2"  "284_1_S_day2" 
 [470] "207_1_C_day2"  "308_3_S_day2"  "293_2_S_day2"  "220_3_C_day2"  "284_2_C_day2"  "196_1_C_day2"  "290_1_S_day2" 
 [477] "195_3_S_day2"  "214_3_S_day2"  "200_3_S_day2"  "300_2_C_day2"  "200_2_S_day2"  "195_2_C_day2"  "288_3_S_day2" 
 [484] "197_1_C_day2"  "285_2_C_day2"  "200_1_C_day2"  "211_1_C_day2"  "279_3_C_day2"  "301_2_C_day2"  "308_1_S_day2" 
 [491] "288_2_S_day2"  "301_3_S_day2"  "308_1_C_day2"  "279_2_C_day2"  "294_2_S_day2"  "213_3_C_day2"  "306_2_C_day2" 
 [498] "194_2_S_day2"  "286_1_C_day2"  "197_2_C_day2"  "291_1_S_day2"  "280_2_C_day2"  "287_3_C_day2"  "199_2_C_day2" 
 [505] "279_1_C_day2"  "235_1_C_day2"  "294_1_C_day2"  "213_1_S_day2"  "290_2_S_day2"  "195_1_S_day2"  "278_2_S_day2" 
 [512] "283_3_C_day2"  "290_3_S_day2"  "294_1_S_day2"  "199_3_S_day2"  "293_3_C_day2"  "212_2_S_day2"  "197_3_C_day2" 
 [519] "282_1_S_day2"  "198_1_S_day2"  "291_2_C_day2"  "198_2_S_day2"  "291_1_C_day2"  "292_2_S_day2"  "198_1_C_day2" 
 [526] "220_3_S_day2"  "200_2_C_day2"  "286_3_S_day2"  "283_1_C_day2"  "293_1_S_day2"  "300_3_S_day2"  "200_3_C_day2" 
 [533] "201_2_C_day2"  "293_4_C_day2"  "301_2_S_day2"  "308_2_S_day2"  "211_1_S_day2"  "307_2_S_day2"  "294_3_C_day2" 
 [540] "291_3_S_day2"  "282_3_S_day2"  "201_3_S_day2"  "230_2_C_day1"  "234_1_C_day1"  "173_4_C_day1"  "084_3_C_day1" 
 [547] "240_4_C_day1"  "236_4_C_day1"  "241_1_C_day1"  "231_2_S_day1"  "176_3_S_day1"  "064_3_S_day1"  "228_1_C_day1" 
 [554] "244_1_S_day1"  "237_1_C_day1"  "228_1_S_day1"  "174_3_C_day1"  "274_1_C_day1"  "249_3_S_day1"  "247_2_S_day1" 
 [561] "091_4_S_day1"  "091_4_C_day1"  "227_2_C_day1"  "237_3_C_day1"  "228_2_C_day1"  "250_1_C_day1"  "093_3_S_day1" 
 [568] "298_1_S_day1"  "240_1_C_day1"  "229_3_S_day1"  "250_4_S_day1"  "274_2_C_day1"  "093_1_C_day1"  "091_1_C_day1" 
 [575] "230_1_S_day1"  "271_2_S_day1"  "084_1_S_day1"  "227_3_C_day1"  "229_3_C_day1"  "236_1_S_day1"  "239_4_S_day1" 
 [582] "221_1_C_day1"  "234_1_S_day1"  "233_2_C_day1"  "225_1_S_day1"  "084_3_S_day1"  "245_3_C_day1"  "239_3_C_day1" 
 [589] "244_3_S_day1"  "250_3_S_day1"  "176_1_S_day1"  "228_3_C_day1"  "038_3_S_day1"  "273_1_S_day1"  "248_1_C_day1" 
 [596] "298_2_S_day1"  "089_2_S_day1"  "274_3_C_day1"  "231_2_C_day1"  "239_1_C_day1"  "085_2_C_day1"  "093_2_C_day1" 
 [603] "259_1_C_day1"  "084_2_S_day1"  "175_3_C_day1"  "084_4_C_day1"  "273_2_C_day1"  "173_4_S_day1"  "240_4_S_day1" 
 [610] "274_4_C_day1"  "236_2_C_day1"  "084_2_C_day1"  "093_4_C_day1"  "250_4_C_day1"  "174_1_C_day1"  "038_1_S_day1" 
 [617] "176_4_C_day1"  "176_2_C_day1"  "064_2_S_day1"  "241_2_S_day1"  "259_3_S_day1"  "259_3_C_day1"  "227_2_S_day1" 
 [624] "240_1_S_day1"  "087_2_S_day1"  "221_2_C_day1"  "174_3_S_day1"  "235_1_S_day1"  "086_3_S_day1"  "086_1_S_day1" 
 [631] "249_2_S_day1"  "176_4_S_day1"  "175_2_S_day1"  "236_3_C_day1"  "092_2_S_day1"  "222_2_C_day1"  "225_2_C_day1" 
 [638] "222_1_S_day1"  "274_4_S_day1"  "090_1_C_day1"  "236_4_S_day1"  "248_1_S_day1"  "298_3_C_day1"  "064_3_C_day1" 
 [645] "175_1_C_day1"  "093_1_S_day1"  "173_2_S_day1"  "230_3_C_day1"  "273_1_C_day1"  "247_1_C_day1"  "237_2_C_day1" 
 [652] "239_2_C_day1"  "237_4_C_day1"  "271_1_S_day1"  "239_3_S_day1"  "087_4_S_day1"  "233_1_S_day1"  "174_4_C_day1" 
 [659] "174_4_S_day1"  "087_1_C_day1"  "092_4_S_day1"  "273_2_S_day1"  "245_2_S_day1"  "245_1_C_day1"  "091_1_S_day1" 
 [666] "233_2_S_day1"  "241_1_S_day1"  "244_1_C_day1"  "087_2_C_day1"  "064_1_S_day1"  "248_3_C_day1"  "273_3_S_day1" 
 [673] "250_2_C_day1"  "273_4_C_day1"  "222_1_C_day1"  "248_2_S_day1"  "093_4_S_day1"  "271_3_S_day1"  "237_1_S_day1" 
 [680] "248_3_S_day1"  "091_2_C_day1"  "175_4_S_day1"  "088_2_C_day1"  "086_2_S_day1"  "237_4_S_day1"  "089_1_S_day1" 
 [687] "250_2_S_day1"  "091_3_C_day1"  "038_2_C_day1"  "174_2_C_day1"  "234_3_C_day1"  "233_4_C_day1"  "227_1_S_day1" 
 [694] "237_2_S_day1"  "173_3_S_day1"  "249_1_C_day1"  "229_2_S_day1"  "222_2_S_day1"  "239_4_C_day1"  "233_1_C_day1" 
 [701] "247_3_S_day1"  "088_1_C_day1"  "234_2_C_day1"  "092_4_C_day1"  "240_2_S_day1"  "173_1_C_day1"  "221_1_S_day1" 
 [708] "084_1_C_day1"  "233_3_S_day1"  "247_4_S_day1"  "236_2_S_day1"  "174_1_S_day1"  "236_3_S_day1"  "245_3_S_day1" 
 [715] "245_1_S_day1"  "229_4_C_day1"  "259_1_S_day1"  "175_1_S_day1"  "245_4_S_day1"  "064_1_C_day1"  "244_2_S_day1" 
 [722] "227_1_C_day1"  "176_1_C_day1"  "229_4_S_day1"  "090_1_S_day1"  "090_3_S_day1"  "087_1_S_day1"  "235_2_S_day1" 
 [729] "090_3_C_day1"  "085_2_S_day1"  "175_4_C_day1"  "230_3_S_day1"  "085_3_S_day1"  "173_1_S_day1"  "086_1_C_day1" 
 [736] "228_2_S_day1"  "273_3_C_day1"  "231_3_C_day1"  "091_2_S_day1"  "176_2_S_day1"  "271_1_C_day1"  "228_3_S_day1" 
 [743] "239_1_S_day1"  "230_2_S_day1"  "173_2_C_day1"  "093_2_S_day1"  "240_3_C_day1"  "092_1_C_day1"  "244_3_C_day1" 
 [750] "092_3_C_day1"  "240_2_C_day1"  "298_1_C_day1"  "274_1_S_day1"  "173_3_C_day1"  "225_1_C_day1"  "234_2_S_day1" 
 [757] "089_3_C_day1"  "247_1_S_day1"  "241_2_C_day1"  "247_3_C_day1"  "259_2_S_day1"  "089_1_C_day1"  "038_2_S_day1" 
 [764] "085_1_S_day1"  "234_3_S_day1"  "247_2_C_day1"  "228_4_C_day1"  "086_3_C_day1"  "248_4_C_day1"  "038_3_C_day1" 
 [771] "230_1_C_day1"  "233_3_C_day1"  "271_4_S_day1"  "175_2_C_day1"  "249_2_C_day1"  "225_2_S_day1"  "087_4_C_day1" 
 [778] "090_2_C_day1"  "249_3_C_day1"  "084_4_S_day1"  "250_1_S_day1"  "237_3_S_day1"  "233_4_S_day1"  "231_1_S_day1" 
 [785] "175_3_S_day1"  "271_2_C_day1"  "092_1_S_day1"  "038_1_C_day1"  "064_2_C_day1"  "088_1_S_day1"  "088_3_C_day1" 
 [792] "092_2_C_day1"  "090_2_S_day1"  "231_1_C_day1"  "089_2_C_day1"  "091_3_S_day1"  "092_3_S_day1"  "229_1_S_day1" 
 [799] "093_3_C_day1"  "239_2_S_day1"  "087_3_C_day1"  "250_3_C_day1"  "229_1_C_day1"  "248_2_C_day1"  "273_4_S_day1" 
 [806] "229_2_C_day1"  "235_1_C_day1"  "244_2_C_day1"  "085_3_C_day1"  "271_4_C_day1"  "089_4_S_day1"  "259_2_C_day1" 
 [813] "274_2_S_day1"  "087_3_S_day1"  "274_3_S_day1"  "241_3_S_day1"  "245_2_C_day1"  "086_2_C_day1"  "088_3_S_day1" 
 [820] "228_4_S_day1"  "231_3_S_day1"  "247_4_C_day1"  "176_3_C_day1"  "240_3_S_day1"  "248_4_S_day1"  "241_3_C_day1" 
 [827] "174_2_S_day1"  "085_1_C_day1"  "089_4_C_day1"  "298_2_C_day1"  "298_3_S_day1"  "227_3_S_day1"  "271_3_C_day1" 
 [834] "249_1_S_day1"  "236_1_C_day1"  "089_3_S_day1"  "198_1_S_day5"  "291_2_C_day5"  "282_1_S_day5"  "298_2_C_day5" 
 [841] "292_2_S_day5"  "289_2_S_day5"  "198_2_S_day5"  "291_1_C_day5"  "198_1_C_day5"  "200_2_C_day5"  "300_3_S_day5" 
 [848] "200_3_C_day5"  "283_1_C_day5"  "293_1_S_day5"  "293_4_C_day5"  "211_1_S_day5"  "307_2_S_day5"  "298_1_S_day5" 
 [855] "301_2_S_day5"  "308_2_S_day5"  "282_3_S_day5"  "201_3_S_day5"  "294_3_C_day5"  "291_3_S_day5"  "279_2_C_day5" 
 [862] "294_2_S_day5"  "301_3_S_day5"  "308_1_C_day5"  "286_1_C_day5"  "197_2_C_day5"  "213_3_C_day5"  "306_2_C_day5" 
 [869] "194_2_S_day5"  "291_1_S_day5"  "280_2_C_day5"  "279_1_C_day5"  "235_1_C_day5"  "287_3_C_day5"  "199_2_C_day5" 
 [876] "213_1_S_day5"  "290_2_S_day5"  "195_1_S_day5"  "294_1_C_day5"  "290_3_S_day5"  "294_1_S_day5"  "278_2_S_day5" 
 [883] "283_3_C_day5"  "212_2_S_day5"  "197_3_C_day5"  "199_3_S_day5"  "293_3_C_day5"  "291_2_S_day5"  "280_3_C_day5" 
 [890] "298_1_C_day5"  "290_2_C_day5"  "197_3_S_day5"  "220_3_C_day5"  "284_2_C_day5"  "207_1_C_day5"  "308_3_S_day5" 
 [897] "293_2_S_day5"  "214_3_S_day5"  "200_3_S_day5"  "290_1_S_day5"  "212_2_C_day5"  "300_2_C_day5"  "200_2_S_day5" 
 [904] "200_1_C_day5"  "211_1_C_day5"  "197_1_C_day5"  "285_2_C_day5"  "301_2_C_day5"  "308_1_S_day5"  "279_3_C_day5" 
 [911] "288_2_C_day5"  "201_1_C_day5"  "214_2_S_day5"  "189_3_C_day5"  "288_1_C_day5"  "306_1_C_day5"  "207_3_S_day5" 
 [918] "213_3_S_day5"  "199_1_S_day5"  "207_3_C_day5"  "307_3_S_day5"  "212_3_C_day5"  "286_1_S_day5"  "201_1_S_day5" 
 [925] "220_2_C_day5"  "213_1_C_day5"  "294_2_C_day5"  "277_1_C_day5"  "293_2_C_day5"  "214_3_C_day5"  "300_1_S_day5" 
 [932] "283_2_C_day5"  "292_1_C_day5"  "294_3_S_day5"  "207_2_C_day5"  "299_3_C_day5"  "301_1_C_day5"  "292_3_C_day5" 
 [939] "194_2_C_day5"  "278_2_C_day5"  "214_2_C_day5"  "285_1_S_day5"  "212_3_S_day5"  "284_1_C_day5"  "286_3_C_day5" 
 [946] "306_1_S_day5"  "211_3_C_day5"  "283_3_S_day5"  "279_3_S_day5"  "283_1_S_day5"  "192_3_C_day5"  "277_2_C_day5" 
 [953] "300_2_S_day5"  "195_1_C_day5"  "197_2_S_day5"  "197_1_S_day5"  "198_3_S_day5"  "287_2_C_day5"  "301_3_C_day5" 
 [960] "282_2_C_day5"  "288_3_C_day5"  "299_1_S_day5"  "300_3_C_day5"  "277_2_S_day5"  "307_1_C_day5"  "201_3_C_day5" 
 [967] "291_3_C_day5"  "196_1_S_day5"  "207_2_S_day5"  "220_1_S_day5"  "2800_3_S_day5" "278_3_S_day5"  "306_3_S_day5" 
 [974] "290_1_C_day5"  "306_3_C_day5"  "199_3_C_day5"  "199_1_C_day5"  "214_1_S_day5"  "277_1_S_day5"  "211_2_S_day5" 
 [981] "211_2_C_day5"  "285_3_C_day5"  "207_1_S_day5"  "298_3_C_day5"  "282_1_C_day5"  "211_3_S_day5"  "308_3_C_day5" 
 [988] "307_3_C_day5"  "200_1_S_day5"  "287_1_C_day5"  "301_1_S_day5"  "298_3_S_day5"  "308_2_C_day5"  "283_2_S_day5" 
 [995] "299_1_C_day5"  "278_3_C_day5"  "213_2_S_day5"  "287_3_S_day5"  "280_1_C_day5"  "220_1_C_day5" 
 [ reached getOption("max.print") -- omitted 4101 entries ]
Pareto_all$arbor.name <- gsub(" ", "", Pareto_all$arbor.name)
meta$arbor.name <- gsub(" ", "", meta$arbor.name)

Pareto_meta <- merge(Pareto_all, meta, by="arbor.name")
Pareto_meta
dim(Pareto_meta)
[1] 4617   13

Let’s clean up this pareto_meta file:

colnames(Pareto_meta)
 [1] "arbor.name"                                "pareto.front.distance"                    
 [3] "pareto.front.location"                     "pareto.front.scaling.distance"            
 [5] "pareto.front.scaling.location087_1_C_day4" "X1.072667"                                
 [7] "X0.830000"                                 "experiment"                               
 [9] "day"                                       "Picture.."                                
[11] "genotype"                                  "replicate"                                
[13] "condition"                                
Pareto <- Pareto_meta[,c(8:13, 1:5)]
dim(Pareto)
[1] 4617   11
colnames(Pareto)[11] <- "pareto.front.scaling.location"
Pareto

Now - let’s try and connect it to the MR_all3 file:

all_MR3
unique(all_MR3$genotype)
  [1] " 189" " 292" " 213" " 212" " 307" " 282" " 298" " 301" " 286" " 214" " 194" " 294" " 285" " 293" " 284" " 278"
 [17] " 300" " 201" " 279" " 280" " 299" " 200" " 211" " 308" " 197" " 287" " 196" " 220" " 207" " 290" " 198" " 195"
 [33] " 289" " 288" " 291" " 199" " 277" " 283" " 306" " 235" " 192" " 147" " 252" " 166" " 269" " 064" " 253" " 193"
 [49] " 146" " 141" " 251" " 139" " 169" " 258" " 144" " 138" " 061" " 065" " 170" " 142" " 140" " 168" " 272" " 165"
 [65] " 255" " 260" " 264" " 262" " 261" " 167" " 060" " 066" " 136" " 256" " 143" " 171" " 082" " 083" " 191" " 259"
 [81] " 062" " 172" " 063" " 270" " 268" " 267" " 234" " 245" " 173" " 236" " 084" " 229" " 241" " 231" " 227" " 176"
 [97] " 087" " 091" " 090" " 085" " 228" " 230" " 175" " 250" " 222" " 239" " 233" " 274" " 088" " 271" " 240" " 092"
[113] " 089" " 247" " 038" " 248" " 086" " 273" " 244" " 093" " 174" " 249" " 237" " 221" " 225" " 103" " 028" " 098"
[129] " 055" " 075" " 059" " 101" " 034" " 002" " 030" " 056" " 001" " 102" " 012" " 076" " 079" " 104" " 081" " 096"
[145] " 058" " 099" " 105" " 040" " 035" " 094" " 074" " 032" " 022" " 003" " 095" " 009" " 106" " 057" " 033" " 029"
[161] " 013" " 031" " 007" " 008" " 006" " 080" " 005" " 036" " 011" " 078" " 010" " 097" " 037"
all_MR3$arbor.name <- paste(all_MR3$genotype, "_", all_MR3$rep, "_", all_MR3$cond, "_DAS", all_MR3$DAS, sep="")
head(all_MR3)

all_MR3$arbor.name <- gsub("DAS0", "day1", all_MR3$arbor.name)
all_MR3$arbor.name <- gsub("DAS1", "day2", all_MR3$arbor.name)
all_MR3$arbor.name <- gsub("DAS2", "day3", all_MR3$arbor.name)
all_MR3$arbor.name <- gsub("DAS3", "day4", all_MR3$arbor.name)
all_MR3$arbor.name <- gsub("DAS4", "day5", all_MR3$arbor.name)
all_MR3$arbor.name <- gsub(" ", "", all_MR3$arbor.name)
head(all_MR3)
unique(all_MR3$arbor.name) %in% unique(Pareto$arbor.name)
   [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
  [19]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
  [37]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
  [55]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
  [73]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
  [91]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [109]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [127]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [145]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [163]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [181]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [199]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [217]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [235]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [253]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [271]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [289]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [307]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [325]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [343]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [361]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [379]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE
 [397]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [415]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [433]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [451]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [469]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [487]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [505]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [523]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [541]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [559]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [577]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [595]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE
 [613]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [631]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [649]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [667]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [685]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [703]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [721]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [739]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [757]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [775]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [793]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [811]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [829]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [847]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [865]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [883]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [901]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [919]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [937]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [955]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [973]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [991]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [ reached getOption("max.print") -- omitted 4297 entries ]
all_MR4 <- merge(all_MR3, Pareto, by="arbor.name")
dim(all_MR4)
[1] 4990   75
all_MR4

Let’s clean it up a little before going further:

Pareto through time:

Now we have all the data - let’s have a look at how that is looking through time:

all_MR5 <- na.omit(all_MR4)
all_MR5$DAS <- as.factor(all_MR5$DAS)

PFdist_lgraph <- ggplot(data=all_MR5, aes(x= DAS, y=pareto.front.distance, group = root_name, color = cond)) 
PFdist_lgraph <- PFdist_lgraph +geom_line(alpha = 0.1) 
PFdistance_lgraph <- PFdistance_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)
PFdistance_lgraph <- PFdistance_lgraph + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
PFdistance_lgraph <- PFdistance_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)

PFdistance_lgraph <- PFdistance_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Individual accessions")
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
PFdistance_lgraph <- PFdistance_lgraph + ylab("Pareto Front Distance (a.u.)") + xlab("Days After Stress") + theme(legend.position='none')
PFdistance_lgraph

PFscdist_lgraph <- ggplot(data=all_MR5, aes(x= DAS, y=pareto.front.scaling.distance, group = root_name, color = cond)) 
PFscdist_lgraph <- PFscdist_lgraph +geom_line(alpha = 0.1) 
PFscdist_lgraph <- PFscdist_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)
PFscdist_lgraph <- PFscdist_lgraph + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
PFscdist_lgraph <- PFscdist_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)

PFscdist_lgraph <- PFscdist_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Individual accessions")
PFscdist_lgraph <- PFscdist_lgraph + ylab("Pareto Front Scaling Distance (a.u.)") + xlab("Days After Stress") + theme(legend.position='none')
PFscdist_lgraph

PFloc_lgraph <- ggplot(data=all_MR5, aes(x= DAS, y=pareto.front.location, group = root_name, color = cond)) 
PFloc_lgraph <- PFloc_lgraph +geom_line(alpha = 0.1) 
PFloc_lgraph <- PFloc_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)
PFloc_lgraph <- PFloc_lgraph + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
PFloc_lgraph <- PFloc_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
PFloc_lgraph <- PFloc_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Individual accessions")
PFloc_lgraph <- PFloc_lgraph + ylab("Pareto Front Location (a.u.)") + xlab("Days After Stress") + theme(legend.position='none')
PFloc_lgraph

PFscloc_lgraph <- ggplot(data=all_MR5, aes(x= DAS, y=pareto.front.scaling.location, group = root_name, color = cond)) 
PFscloc_lgraph <- PFscloc_lgraph +geom_line(alpha = 0.1) 
PFscloc_lgraph <- PFscloc_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)
PFscloc_lgraph <- PFscloc_lgraph + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
PFscloc_lgraph <- PFscloc_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
PFscloc_lgraph <- PFscloc_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Individual accessions")
PFscloc_lgraph <- PFscloc_lgraph + ylab("Pareto Front Scaling Location (a.u.)") + xlab("Days After Stress") + theme(legend.position='none')
PFscloc_lgraph

ok - now let’s have a look what is the reproducibility of the pareto front location within the genotype:

interesting <- subset(all_MR5, all_MR5$genotype == " 248")
interesting

M248_PFScloc <- ggplot(data=interesting, aes(x= DAS, y=pareto.front.scaling.location, group = root_name, color = cond)) 
M248_PFScloc <- M248_PFScloc +geom_line(alpha = 0.2) 
M248_PFScloc <- M248_PFScloc + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)
M248_PFScloc <- M248_PFScloc + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
M248_PFScloc <- M248_PFScloc + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
M248_PFScloc <- M248_PFScloc + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("M248")
M248_PFScloc <- M248_PFScloc + ylab("Pareto Front Scaling Location") + xlab("Days After Stress") + theme(legend.position='none')
M248_PFScloc

Let’s save this file and explore the heritability of these traits in MVApp:

write.csv(all_MR5, "Big01to04_incl.PF.csv", row.names = FALSE)

The heritabiity of all the traits is pretty decent overall - between 0.4 and 0.7 in most cases.

Let’s see how the Pareto Front Scaling Location is correlated with LR traits:

all_MR5$DAS <- as.factor(all_MR5$DAS)
PFsc.loc_vs_TRS <- ggscatter(all_MR5, x = "pareto.front.scaling.location", y = "TRS", color = "cond", size = 0.3, 
                            rug = TRUE, facet.by = "DAS") + stat_cor(method = "pearson")
PFsc.loc_vs_TRS

PFsc.loc_vs_LRno <- ggscatter(all_MR5, x = "pareto.front.scaling.location", y = "LRno", color = "cond", size = 0.3, 
                            rug = TRUE, facet.by = "DAS") + stat_cor(method = "pearson")
PFsc.loc_vs_LRno

PFsc.loc_vs_aLRL <- ggscatter(all_MR5, x = "pareto.front.scaling.location", y = "aLRL", color = "cond", size = 0.3, 
                            rug = TRUE, facet.by = "DAS") + stat_cor(method = "pearson")
PFsc.loc_vs_aLRL

PFsc.loc_vs_CoG <- ggscatter(all_MR5, x = "pareto.front.scaling.location", y = "CoG", color = "cond", size = 0.3, 
                            rug = TRUE, facet.by = "DAS") + stat_cor(method = "pearson")
PFsc.loc_vs_CoG

actually - CoG should be calculated as perc. or MR - I wonder why I didnt do that before :)

colnames(all_MR5)
 [1] "arbor.name"                    "image"                         "root_name"                    
 [4] "root"                          "experiment"                    "DAS"                          
 [7] "genotype"                      "rep"                           "cond"                         
[10] "MRL"                           "Apical"                        "Branched"                     
[13] "Basal"                         "Apical_perc"                   "Branched_perc"                
[16] "Basal_perc"                    "LR_no_10_100"                  "LR_no_20_100"                 
[19] "LR_no_30_100"                  "LR_no_40_100"                  "LR_no_50_100"                 
[22] "LR_no_60_100"                  "LR_no_70_100"                  "LR_no_80_100"                 
[25] "LR_no_90_100"                  "LR_no_100_100"                 "LRL_10_100"                   
[28] "LRL_20_100"                    "LRL_30_100"                    "LRL_40_100"                   
[31] "LRL_50_100"                    "LRL_60_100"                    "LRL_70_100"                   
[34] "LRL_80_100"                    "LRL_90_100"                    "LRL_100_100"                  
[37] "CoG"                           "LRL.dec"                       "LRL.dec.R2"                   
[40] "LRL"                           "LRno"                          "aLRL"                         
[43] "TRS"                           "MRL.p.TRS"                     "aLRL.p.TRS"                   
[46] "LRL_10_perc"                   "LRL_20_perc"                   "LRL_30_perc"                  
[49] "LRL_40_perc"                   "LRL_50_perc"                   "LRL_60_perc"                  
[52] "LRL_70_perc"                   "LRL_80_perc"                   "LRL_90_perc"                  
[55] "LRL_100_perc"                  "LRno_10_perc"                  "LRno_20_perc"                 
[58] "LRno_30_perc"                  "LRno_40_perc"                  "LRno_50_perc"                 
[61] "LRno_60_perc"                  "LRno_70_perc"                  "LRno_80_perc"                 
[64] "LRno_90_perc"                  "LRno_100_perc"                 "pareto.front.distance"        
[67] "pareto.front.location"         "pareto.front.scaling.distance" "pareto.front.scaling.location"
[70] "CoG.per"                      
all_MR5$CoG.per <- all_MR5$CoG / all_MR5$MRL

CoGperc_lgraph <- ggplot(data=all_MR5, aes(x= DAS, y=CoG.per, group = root_name, color = cond)) 
CoGperc_lgraph <- CoGperc_lgraph +geom_line(alpha = 0.1) 
CoGperc_lgraph <- CoGperc_lgraph + stat_summary(fun.data = mean_se, geom="ribbon", linetype=0, aes(group=cond), alpha=0.3)
CoGperc_lgraph <- CoGperc_lgraph + stat_summary(fun.y=mean, aes(group= cond),  size=0.7, geom="line", linetype = "dashed")
`fun.y` is deprecated. Use `fun` instead.
CoGperc_lgraph <- CoGperc_lgraph + stat_compare_means(aes(group = cond), label = "p.signif", method = "t.test", hide.ns = T)
CoGperc_lgraph <- CoGperc_lgraph + scale_colour_manual(values = c("steelblue", "firebrick3")) + ggtitle("Individual accessions")
CoGperc_lgraph <- CoGperc_lgraph + ylab("Fraction of the Main Root") + xlab("Days After Stress") + theme(legend.position='none')
CoGperc_lgraph


PFsc.loc_vs_CoG.perc <- ggscatter(all_MR5, x = "pareto.front.scaling.location", y = "CoG.per", color = "cond", size = 0.3, 
                            rug = TRUE, facet.by = "DAS") + stat_cor(method = "pearson")
PFsc.loc_vs_CoG.perc

Also - I would like to have a look at how this scaling.location looks across the accessions within one day and between conditions - lets do DAS4

DAS4 <- subset(all_MR5, all_MR5$DAS == 4)

grand.means <- aggregate(pareto.front.scaling.location ~ cond, data = DAS4, FUN = mean)
grand.means

unique(DAS4$genotype)
  [1] " 001" " 002" " 003" " 005" " 006" " 007" " 008" " 009" " 010" " 011" " 012" " 013" " 022" " 028" " 029" " 030"
 [17] " 031" " 032" " 033" " 034" " 035" " 036" " 037" " 038" " 040" " 055" " 056" " 057" " 058" " 059" " 060" " 061"
 [33] " 062" " 063" " 064" " 065" " 066" " 074" " 075" " 076" " 078" " 079" " 080" " 081" " 082" " 083" " 084" " 085"
 [49] " 086" " 087" " 088" " 089" " 090" " 091" " 092" " 093" " 094" " 095" " 096" " 097" " 098" " 099" " 101" " 102"
 [65] " 103" " 104" " 105" " 106" " 136" " 138" " 139" " 140" " 141" " 142" " 143" " 144" " 146" " 147" " 165" " 166"
 [81] " 167" " 168" " 169" " 170" " 171" " 172" " 173" " 174" " 175" " 176" " 189" " 191" " 192" " 193" " 194" " 195"
 [97] " 196" " 197" " 198" " 199" " 200" " 201" " 207" " 211" " 212" " 213" " 214" " 220" " 221" " 222" " 225" " 227"
[113] " 228" " 229" " 230" " 231" " 233" " 234" " 235" " 236" " 237" " 239" " 240" " 241" " 244" " 245" " 247" " 248"
[129] " 249" " 250" " 251" " 252" " 253" " 255" " 256" " 258" " 259" " 260" " 261" " 262" " 264" " 267" " 268" " 269"
[145] " 270" " 271" " 272" " 273" " 274" " 277" " 278" " 279" " 280" " 282" " 283" " 284" " 285" " 286" " 287" " 288"
[161] " 289" " 290" " 291" " 292" " 293" " 294" " 298" " 299" " 300" " 301" " 306" " 307" " 308"
PF.sc.loc_p_geno <- ggerrorplot(DAS4, y = "pareto.front.scaling.location", x = "genotype", fill="genotype",
                               color="genotype", facet.by = c("cond"), ncol=1, desc_stat = "mean_sd", add = "jitter", 
                               add.params = list(color = "darkgray"), xlab="Genotype", 
                               ylab="Pareto Front Scaling Location (a.u.)") 
PF.sc.loc_p_geno <- PF.sc.loc_p_geno + geom_hline(
                                data = grand.means, aes(yintercept = pareto.front.scaling.location),
                                linetype = 2,
                                group = "cond")
PF.sc.loc_p_geno <- PF.sc.loc_p_geno + rremove("legend") + stat_compare_means(method="t.test", ref.group = ".all.", 
                                                              label = "p.signif", hide.ns = T)
PF.sc.loc_p_geno

Let’s calculate the change in the pareto front scaling location relative to control conditions per accession as well.

LS0tCnRpdGxlOiAiQW5hbHlzaXMgb2YgQUxMIFBpbXAgQklHIGV4cGVyaW1lbnQiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCiMgZmlsZSBwcmVwYXJhdGlvbgoKUGltcEJpZzIgZXhwZXJpbWVudCBhbmFseXNpcyAtIGxvYWRpbmcgdGhlIGRhdGEgICAKCmBgYHtyfQpzZXR3ZCgiL1VzZXJzL21hZ2RhbGVuYS9Ecm9wYm94L0RhdGFBbmRBbmFseXNpcy9Ub21hdG8vUGltcGlCSUcgY3N2IHJhdyBmaWxlcy8iKQpsaXN0LmZpbGVzKCkKQmlnMV9EMEQxIDwtIHJlYWQuY3N2KCJwaW1waV9CaWcxX0QwX0QxLmNzdiIpCkJpZzFfRDJEMyA8LSByZWFkLmNzdigicGltcGlfQmlnMV9EMl9EMy5jc3YiKQpCaWcxX0Q0RDUgPC0gcmVhZC5jc3YoInBpbXBpX0JpZzFfRDRfRDUuY3N2IikKCkJpZzJfRDBEMSA8LSByZWFkLmNzdigicGltcGlfQmlnMl9EMF9EMS5jc3YiKQpCaWcyX0QyRDMgPC0gcmVhZC5jc3YoInBpbXBpX0JpZzJfRDJfRDMuY3N2IikKQmlnMl9ENEQ1IDwtIHJlYWQuY3N2KCJwaW1waV9CaWcyX0Q0X0Q1LmNzdiIpCgpCaWczX0QwRDEgPC0gcmVhZC5jc3YoInBpbXBpX0JpZzNfRDBfRDEuY3N2IikKQmlnM19EMkQzIDwtIHJlYWQuY3N2KCJwaW1waV9CaWczX0QyX0QzLmNzdiIpCkJpZzNfRDRENSA8LSByZWFkLmNzdigicGltcGlfQmlnM19ENF9ENS5jc3YiKQoKQmlnNF9EMEQxIDwtIHJlYWQuY3N2KCJwaW1waV9CaWc0X0QwX0QxLmNzdiIpCkJpZzRfRDBfRlUgPC0gcmVhZC5jc3YoInBpbXBpX0JpZzRfRDBfRlUuY3N2IikKQmlnNF9EMkQzIDwtIHJlYWQuY3N2KCJwaW1waV9CaWc0X0QyX0QzLmNzdiIpCkJpZzRfRDRENSA8LSByZWFkLmNzdigicGltcGlfQmlnNF9ENF9ENS5jc3YiKQoKaGVhZChCaWc0X0QwRDEpCmhlYWQoQmlnNF9EMF9GVSkKIyBOZWVkIHRvIGFkZCB0aGlzIGJlY2F1c2Ugb3RoZXJ3aXNlIHdlIGhhdmUgaW1hZ2VzIHRoYXQgYXJlIGNhbGxlZCBleGFjdGx5IHRoZSBzYW1lIGFuZCBpdCBpcyBjYXVzaW5nIHByb2JsZW1zIGxhdGVyIG9uIApCaWc0X0QwX0ZVJGltYWdlIDwtIGdzdWIoIi5yc21sIiwgIl9GVS5yc21sIiwgQmlnNF9EMF9GVSRpbWFnZSkKaGVhZChCaWc0X0QwX0ZVKQpoZWFkKEJpZzRfRDJEMykKaGVhZChCaWc0X0Q0RDUpCmBgYAoKTGV0J3MgZnVzZSBhbGwgdGhlIGZpbGVzIGludG8gb25lIGJpZyBmaWxlIHBlciBleHBlcmltZW50CgpgYGB7cn0KQmlnMSA8LSByYmluZChCaWcxX0QwRDEsIEJpZzFfRDJEMykKQmlnMSA8LSByYmluZChCaWcxLCBCaWcxX0Q0RDUpCgpCaWcyIDwtIHJiaW5kKEJpZzJfRDBEMSwgQmlnMl9EMkQzKQpCaWcyIDwtIHJiaW5kKEJpZzIsIEJpZzJfRDRENSkKCkJpZzMgPC0gcmJpbmQoQmlnM19EMEQxLCBCaWczX0QyRDMpCkJpZzMgPC0gcmJpbmQoQmlnMywgQmlnM19ENEQ1KQoKQmlnNCA8LSByYmluZChCaWc0X0QwRDEsIEJpZzRfRDBfRlUpCkJpZzQgPC0gcmJpbmQoQmlnNCwgQmlnNF9EMkQzKQpCaWc0IDwtIHJiaW5kKEJpZzQsIEJpZzRfRDRENSkKYGBgCgpMZXQncyBtYWtlIHN1cmUgd2UgaGF2ZSBhIGNvbGx1bW4gaW5kaWNhdGluZyB0aGUgZXhwZXJpbWVudGFsIGJhdGNoIGFzIHdlbGw6CgpgYGB7cn0KQmlnMSRleHBlcmltZW50IDwtICJCaWcwMSIKQmlnMiRleHBlcmltZW50IDwtICJCaWcwMiIKQmlnMyRleHBlcmltZW50IDwtICJCaWcwMyIKQmlnNCRleHBlcmltZW50IDwtICJCaWcwNCIKYGBgCgpUaGVyZSBpcyBhbiBpc3N1ZSB3aXRoIHRoZSBpbWFnZXMgZnJvbSBCaWcwMiBhbHNvIGJlaW5nIGluIEJpZzA0IC0gc28gd2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCB3ZSBoYXZlIG9ubHkgaW1hZ2VzIGZyb20gcGFydGljdWxhciBleHBlcmltZW50IGluIHRoZXJlLiBTbyAtIHdlIG5lZWQgdG8gbWFrZSBhIGNvbGx1bW4gZm9yIGV2ZXJ5b25lIHdpdGggImRhdGUiIHRvIG1ha2Ugc3VyZSB3ZSBvbmx5IGhhdmUgdGhlIGZvbGxvd2luZyBkYXlzCgpCaWcgMSBleHBlcmltZW50OgpgYGB7cn0KQmlnMSRpbmZvIDwtIHN0cnNwbGl0KEJpZzEkaW1hZ2UsICJfIikKZGltKEJpZzEpCkJpZzEkZGF0ZSA8LSAibm9uZSIKZm9yKGkgaW4gMTo4NTU1KXsKICBCaWcxJGRhdGVbaV0gPC0gc2FwcGx5KEJpZzEkaW5mb1tpXSwgZnVuY3Rpb24oeCl7CiAgeFs0XX0pCn0KdW5pcXVlKEJpZzEkZGF0ZSkKYGBgCgpCaWcgMiBleHBlcmltZW50OgpgYGB7cn0KQmlnMiRpbmZvIDwtIHN0cnNwbGl0KEJpZzIkaW1hZ2UsICJfIikKZGltKEJpZzIpCkJpZzIkZGF0ZSA8LSAibm9uZSIKZm9yKGkgaW4gMToxMzY5NSl7CiAgQmlnMiRkYXRlW2ldIDwtIHNhcHBseShCaWcyJGluZm9baV0sIGZ1bmN0aW9uKHgpewogIHhbNF19KQp9CnVuaXF1ZShCaWcyJGRhdGUpCmBgYAoKQmlnIDMgZXhwZXJpbWVudDoKYGBge3J9CkJpZzMkaW5mbyA8LSBzdHJzcGxpdChCaWczJGltYWdlLCAiXyIpCmRpbShCaWczKQpCaWczJGRhdGUgPC0gIm5vbmUiCmZvcihpIGluIDE6MTMyMzIpewogIEJpZzMkZGF0ZVtpXSA8LSBzYXBwbHkoQmlnMyRpbmZvW2ldLCBmdW5jdGlvbih4KXsKICB4WzRdfSkKfQp1bmlxdWUoQmlnMyRkYXRlKQpgYGAKCkJpZyA0IGV4cGVyaW1lbnQ6CmBgYHtyfQpCaWc0JGluZm8gPC0gc3Ryc3BsaXQoQmlnNCRpbWFnZSwgIl8iKQpkaW0oQmlnNCkKQmlnNCRkYXRlIDwtICJub25lIgpmb3IoaSBpbiAxOjEzMzQ2KXsKICBCaWc0JGRhdGVbaV0gPC0gc2FwcGx5KEJpZzQkaW5mb1tpXSwgZnVuY3Rpb24oeCl7CiAgeFs0XX0pCn0KdW5pcXVlKEJpZzQkZGF0ZSkKYGBgCgpOb3cgd2UgY2FuIGZ1c2UgYWxsIHRoZSBkYXRhIGludG8gb25lOgoKYGBge3J9CmFsbF9kYXRhIDwtIHJiaW5kKEJpZzEsIEJpZzIpCmFsbF9kYXRhIDwtIHJiaW5kKGFsbF9kYXRhLCBCaWczKQphbGxfZGF0YSA8LSByYmluZChhbGxfZGF0YSwgQmlnNCkKZGltKGFsbF9kYXRhKQpgYGAKClRoZW4gLSB3ZSBuZWVkIHRvIGNoZWNrIGhvdyBtYW55ICJSb290IiB2YWx1ZXMgd2UgaGF2ZSBwZXIgdW5pcXVlIGltYWdlIGFuZCBob3cgbWFueSAiTGF0ZXJhbCByb290IiB2YWx1ZXMgd2UgaGF2ZS4gVGhpcyB3aWxsIHNhdmUgdXMgaGVhcHMgb2YgaGVhZGFjaGUgaW4gdGhlIGZ1dHVyZQoKSW4gdG90YWwgd2UgaGF2ZSBYIG1hbnkgaW1hZ2VzCmBgYHtyfQpsZW5ndGgodW5pcXVlKGFsbF9kYXRhJGltYWdlKSkKYGBgCgphbmQgd2UgaGF2ZSBYIG1hbnkgTWFpbiBSb290cyAtIHdoaWNoICpzaG91bGQqIGJlIHRoZSBzYW1lIGFzIGltYWdlIG51bWJlci4uLgoKYGBge3J9Cm9ubHlNciA8LSBzdWJzZXQoYWxsX2RhdGEsIGFsbF9kYXRhJHJvb3Rfb3JkZXIgPT0gMCkKZGltKG9ubHlNcikKYGBgCgouLi4gYnV0IGl0IGlzbid0IC0gc28gbGV0J3MgZmlndXJlIHdoaWNoIGltYWdlcyBoYXZlIG1vcmUgTVIgcGVyIGltYWdlIHRoYW4gMSBhbmQgcmVtb3ZlIHRoZXNlIHNwZWNpZmljIHZhbHVlcyAob3IgZGVjaWRlIHdoaWNoIG9uZSB0byByZW1vdmUgOikKCldlIG5lZWQgdG8gbWFrZSBhIGZpbGUgd2hlcmU6CkNvbC4gQSA+IGltYWdlIApDb2wuIEIgPiAjIFJvb3QKQ29sLiBDID4gIyBMYXRlcmFsIFJvb3QKCmBgYHtyfQpuYW1lcyA8LSBjKHRleHQ9ImltYWdlIiwgIk1SLm5vIiwgIkxSLm5vIikKY2hlY2tfdGFibGUgPC0gZGF0YS5mcmFtZSgpCgpmb3IgKGsgaW4gbmFtZXMpIGNoZWNrX3RhYmxlW1trXV0gPC0gYXMuY2hhcmFjdGVyKCkKYGBgCgpUaGVuIC0gd2Ugd2lsbCBzdWJzZXQgdGhlIGVudGlyZSBkYXRhc2V0IGZvciBvbmUgaW1hZ2UgYW5kIGNhbGN1bGF0ZSBob3cgbWFueSBNUiBhbmQgTFIgYXJlIHRoZXJlIGFuZCBpbnRlZ3JhdGUgaXQgaW50byB0aGUgdGFibGUKCmBgYHtyfQppPTEKCnVuaSA8LSBzdWJzZXQoYWxsX2RhdGEsIGFsbF9kYXRhJGltYWdlID09IHVuaXF1ZShhbGxfZGF0YSRpbWFnZSlbaV0pCnVuaQpNUiA8LSBzdWJzZXQodW5pLCB1bmkkcm9vdF9vcmRlciA9PSAwKQpMUiA8LSBzdWJzZXQodW5pLCB1bmkkcm9vdF9vcmRlciA9PSAxKQoKY2hlY2tfdGFibGVbaSwxXSA8LSBhcy5jaGFyYWN0ZXIodW5pcXVlKHVuaSRpbWFnZSkpCmNoZWNrX3RhYmxlW2ksMl0gPC0gZGltKE1SKVsxXQpjaGVja190YWJsZVtpLDNdIDwtIGRpbShMUilbMV0KY2hlY2tfdGFibGUKYGBgCkNvb2wgLSBub3cgbGV0J3MgbG9vcCBpdCBmb3IgYWxsIHRoZSBpbWFnZXM6CmBgYHtyfQoKZm9yIChpIGluIDI6NTUyMSkgewogIHVuaSA8LSBzdWJzZXQoYWxsX2RhdGEsIGFsbF9kYXRhJGltYWdlID09IHVuaXF1ZShhbGxfZGF0YSRpbWFnZSlbaV0pCiAgdW5pCiAgTVIgPC0gc3Vic2V0KHVuaSwgdW5pJHJvb3Rfb3JkZXIgPT0gMCkKICBMUiA8LSBzdWJzZXQodW5pLCB1bmkkcm9vdF9vcmRlciA9PSAxKQogIAogIGNoZWNrX3RhYmxlW2ksMV0gPC0gYXMuY2hhcmFjdGVyKHVuaXF1ZSh1bmkkaW1hZ2UpKQogIGNoZWNrX3RhYmxlW2ksMl0gPC0gZGltKE1SKVsxXQogIGNoZWNrX3RhYmxlW2ksM10gPC0gZGltKExSKVsxXQp9CgpjaGVja190YWJsZQpgYGAKCkNvb2wgLSBub3cgbGV0J3MgZmlzaCBvdXQgYWxsIHRoZSBpbWFnZXMgd2hlcmUgd2UgaGF2ZSBtdWx0aXBsZSBNUjoKCmBgYHtyfQpzdXNwaWNpb3VzIDwtIHN1YnNldChjaGVja190YWJsZSwgY2hlY2tfdGFibGUkTVIubm8gPiAxKQpkaW0oc3VzcGljaW91cykKc3VzcGljaW91cwpgYGAKCkxldCdzIGhhdmUgYSBjbG9zZXIgbG9vayBhdCB0aGVzZSBzdXNwaWNpb3VzIGltYWdlczoKCmBgYHtyfQpjbG9zZXJfbG9vayA8LSBzdWJzZXQoYWxsX2RhdGEsIGFsbF9kYXRhJGltYWdlID09IHN1c3BpY2lvdXMkaW1hZ2VbMTAwXSkKY2xvc2VyX2xvb2syIDwtIHN1YnNldChjbG9zZXJfbG9vaywgY2xvc2VyX2xvb2skcm9vdF9vcmRlciA9PSAwKQpjbG9zZXJfbG9vazIKYGBgCgpJdCBsb29rcyBsaWtlIHRoZXNlIGRvdWJsZSByb290cyBhcmUganVzdCBkdXBsaWNhdGlvbnMgLSBsZXQncyBzZWUgd2hhdCBoYXBwZW5zIHdoZW4gd2UgcmVtb3ZlIGV4YWN0IGR1cGxpY2F0ZXMgdXNpbmcgdGlkeXZlcnNlIHBhY2thZ2UKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYWxsX2RhdGEyIDwtIGFsbF9kYXRhICU+JSBkaXN0aW5jdCgpCmxlbmd0aCh1bmlxdWUoKGFsbF9kYXRhMiRpbWFnZSkpKQoKb25seU1yMiA8LSBzdWJzZXQoYWxsX2RhdGEyLCBhbGxfZGF0YTIkcm9vdF9vcmRlciA9PSAwKQpkaW0ob25seU1yMikKYGBgCgpjb29sIC0gc28gbm93IHdlIGhhdmUgbWFqb3JpdHkgb2YgdGhlIGltYWdlcyB3aGVyZSB0aGUgTVIgaXMgc2ltcGx5IGR1cGxpY2F0ZWQgLSBzbyBsZXQncyByZXBlYXQgdGhlIGV4ZXJjaXNlIGZyb20gYWJvdmUgYWdhaW4gdG8gaWRlbnRpZnkgd2hhdCBvdGhlciBpbWFnZXMgd2UgaGF2ZSBsZWZ0IG92ZXIgd2hpY2ggaGF2ZSB0d28gTVI6CgpgYGB7cn0KbmFtZXMgPC0gYyh0ZXh0PSJpbWFnZSIsICJNUi5ubyIsICJMUi5ubyIpCmNoZWNrX3RhYmxlMiA8LSBkYXRhLmZyYW1lKCkKCmZvciAoayBpbiBuYW1lcykgY2hlY2tfdGFibGUyW1trXV0gPC0gYXMuY2hhcmFjdGVyKCkKCmZvciAoaSBpbiAxOjU1MjEpIHsKICB1bmkgPC0gc3Vic2V0KGFsbF9kYXRhMiwgYWxsX2RhdGEyJGltYWdlID09IHVuaXF1ZShhbGxfZGF0YTIkaW1hZ2UpW2ldKQogIE1SIDwtIHN1YnNldCh1bmksIHVuaSRyb290X29yZGVyID09IDApCiAgTFIgPC0gc3Vic2V0KHVuaSwgdW5pJHJvb3Rfb3JkZXIgPT0gMSkKICAKICBjaGVja190YWJsZTJbaSwxXSA8LSBhcy5jaGFyYWN0ZXIodW5pcXVlKHVuaSRpbWFnZSkpCiAgY2hlY2tfdGFibGUyW2ksMl0gPC0gZGltKE1SKVsxXQogIGNoZWNrX3RhYmxlMltpLDNdIDwtIGRpbShMUilbMV0KfQoKc3VzcGljaW91cyA8LSBzdWJzZXQoY2hlY2tfdGFibGUyLCBjaGVja190YWJsZTIkTVIubm8gPiAxKQpzdXNwaWNpb3VzCmBgYAoKTGV0J3MgaGF2ZSBhIGNsb3NlciBsb29rIGF0IHRoZXNlIGltYWdlcyBhbmQgdGhlaXIgTVJzOgpgYGB7cn0KY2xvc2VyX2xvb2sgPC0gc3Vic2V0KGFsbF9kYXRhMiwgYWxsX2RhdGEyJGltYWdlID09IHN1c3BpY2lvdXMkaW1hZ2VbMV0pCmNsb3Nlcl9sb29rMSA8LSBzdWJzZXQoY2xvc2VyX2xvb2ssIGNsb3Nlcl9sb29rJHJvb3Rfb3JkZXIgPT0gMCkKY2xvc2VyX2xvb2sxCgpjbG9zZXJfbG9vayA8LSBzdWJzZXQoYWxsX2RhdGEyLCBhbGxfZGF0YTIkaW1hZ2UgPT0gc3VzcGljaW91cyRpbWFnZVsyMl0pCmNsb3Nlcl9sb29rMiA8LSBzdWJzZXQoY2xvc2VyX2xvb2ssIGNsb3Nlcl9sb29rJHJvb3Rfb3JkZXIgPT0gMCkKY2xvc2VyX2xvb2syCmBgYAoKT0sgLSBzbyBjbGVhcmx5IC0gd2UgIGhhdmUgc29tZXRoaW5nIHRoYXQgd2FzbnQgY2xhc3NpZmllZCBhcyBMUiBwcm9wZXJseSAoYXMgaW4gY2FzZSBvZiBjbG9zZXJfbG9vazEpLgoKV2UgY2FuIHJlY29nbml6ZSB0aGUgIm1pc3Rha2UgTVIiIGJ5IHNheWluZyB0aGF0IHRoZSBuYW1lIHdvdWxkIHN0YXJ0IHdpdGggcm9vdF8gYnV0IGxldCdzIHNlZSBpZiB0aGlzIGlzIHRoZSBjYXNlIGZvciBtYW55IG9mIHRoZW06CgpgYGB7cn0Kb25seU1yIDwtIHN1YnNldChhbGxfZGF0YTIsIGFsbF9kYXRhMiRyb290X29yZGVyID09IDApCnVuaXF1ZShvbmx5TXIkcm9vdF9uYW1lKQpgYGAKCm9rIC0gc28gdGhlbiB3ZSBoYXZlIHRvIHNwbGl0IHRoZSByb290IG5hbWUgaW50byBpbmRpdmlkdWFsIHRpZXJzIGFuZCBzZWxlY3QgTVIgd2hpY2ggc3RhcnQgd2l0aCAicm9vdF8iOgoKYGBge3J9CmFsbF9kYXRhMiRyb290X2luZm8gPC0gc3Ryc3BsaXQoYWxsX2RhdGEyJHJvb3RfbmFtZSwgIl8iKQpkaW0oYWxsX2RhdGEyKQoKZm9yKGkgaW4gMTo0MTMxNyl7CiAgYWxsX2RhdGEyJGdlbm90eXBlW2ldIDwtIHNhcHBseShhbGxfZGF0YTIkcm9vdF9pbmZvW2ldLCBmdW5jdGlvbih4KXsKICB4WzFdfSkKICBhbGxfZGF0YTIkcmVwW2ldIDwtIHNhcHBseShhbGxfZGF0YTIkcm9vdF9pbmZvW2ldLCBmdW5jdGlvbih4KXsKICB4WzJdfSkKICBhbGxfZGF0YTIkY29uZFtpXSA8LSBzYXBwbHkoYWxsX2RhdGEyJHJvb3RfaW5mb1tpXSwgZnVuY3Rpb24oeCl7CiAgeFszXX0pCn0KCmhlYWQoYWxsX2RhdGEyKQpgYGAKCk5vdyB3ZSBoYXZlIHRvIHN1YnNldCBmb3IgTXIgYW5kIGxvb2sgYXQgdGhlaXIgaW5kaXZpZHVhbCBnZW5vdHlwZSBpbmZvcm1hdGlvbgoKYGBge3J9Cm9ubHlNciA8LSBzdWJzZXQoYWxsX2RhdGEyLCBhbGxfZGF0YTIkcm9vdF9vcmRlciA9PSAwKQpkaW0ob25seU1yKQp1bmlxdWUob25seU1yJGdlbm90eXBlKQpvbmx5TXIkZ2Vub3R5cGUgPC0gZ3N1YigiICIsICIiLCBvbmx5TXIkZ2Vub3R5cGUpCnVuaXF1ZShvbmx5TXIkZ2Vub3R5cGUpCm9ubHlNcjIgPC0gc3Vic2V0KG9ubHlNciwgb25seU1yJGdlbm90eXBlICE9ICJyb290IikKZGltKG9ubHlNcjIpCnVuaXF1ZShvbmx5TXIyJGdlbm90eXBlKQpgYGAKCk5vdyAtIGxldHMgZ2V0IHJpZCBvZiB0aGVzZSBiYWQgTVIgZnJvbSB0aGUgb3JpZ2luYWwgYWxsX2RhdGEyIGZpbGU6CgpgYGB7cn0KYmFkTXIgPC0gc3Vic2V0KG9ubHlNciwgb25seU1yJGdlbm90eXBlID09ICJyb290IikKYmFkTXIKd3JvbmdfTVIgPC0gYmFkTXIkcm9vdAp3cm9uZ19NUgoKYWxsX2RhdGEyX3NpbmdsZV9NUiA8LSBhbGxfZGF0YTJbIShhbGxfZGF0YTIkcm9vdCAlaW4lIHdyb25nX01SKSxdCmRpbShhbGxfZGF0YTJfc2luZ2xlX01SKQpkaW0oYWxsX2RhdGEyKQoKbGVuZ3RoKHVuaXF1ZSgoYWxsX2RhdGEyX3NpbmdsZV9NUiRpbWFnZSkpKQoKb25seU1yMyA8LSBzdWJzZXQoYWxsX2RhdGEyX3NpbmdsZV9NUiwgYWxsX2RhdGEyX3NpbmdsZV9NUiRyb290X29yZGVyID09IDApCmRpbShvbmx5TXIzKQpgYGAKClNvIHdlIHN0aWxsIGhhdmUgNyBpbWFnZXMgdGhhdCBzdXBwb3NlZGx5IGNvbnRhaW4gbW9yZSB0aGFuIDIgcm9vdHMKCkxldCdzIGxvb2sgYXQgdGhlc2UgaW1hZ2VzOgoKYGBge3J9Cm5hbWVzIDwtIGModGV4dD0iaW1hZ2UiLCAiTVIubm8iLCAiTFIubm8iKQpjaGVja190YWJsZTIgPC0gZGF0YS5mcmFtZSgpCgpmb3IgKGsgaW4gbmFtZXMpIGNoZWNrX3RhYmxlMltba11dIDwtIGFzLmNoYXJhY3RlcigpCgpmb3IgKGkgaW4gMTo1NTIwKSB7CiAgdW5pIDwtIHN1YnNldChhbGxfZGF0YTJfc2luZ2xlX01SLCBhbGxfZGF0YTJfc2luZ2xlX01SJGltYWdlID09IHVuaXF1ZShhbGxfZGF0YTJfc2luZ2xlX01SJGltYWdlKVtpXSkKICBNUiA8LSBzdWJzZXQodW5pLCB1bmkkcm9vdF9vcmRlciA9PSAwKQogIExSIDwtIHN1YnNldCh1bmksIHVuaSRyb290X29yZGVyID09IDEpCiAgCiAgY2hlY2tfdGFibGUyW2ksMV0gPC0gYXMuY2hhcmFjdGVyKHVuaXF1ZSh1bmkkaW1hZ2UpKQogIGNoZWNrX3RhYmxlMltpLDJdIDwtIGRpbShNUilbMV0KICBjaGVja190YWJsZTJbaSwzXSA8LSBkaW0oTFIpWzFdCn0KCnN1c3BpY2lvdXMgPC0gc3Vic2V0KGNoZWNrX3RhYmxlMiwgY2hlY2tfdGFibGUyJE1SLm5vID4gMSkKc3VzcGljaW91cwpgYGAKCmBgYHtyfQpjbG9zZXJfbG9vayA8LSBzdWJzZXQoYWxsX2RhdGEyX3NpbmdsZV9NUiwgYWxsX2RhdGEyX3NpbmdsZV9NUiRpbWFnZSA9PSBzdXNwaWNpb3VzJGltYWdlWzFdKQpjbG9zZXJfbG9vazEgPC0gc3Vic2V0KGNsb3Nlcl9sb29rLCBjbG9zZXJfbG9vayRyb290X29yZGVyID09IDApCmNsb3Nlcl9sb29rMQoKY2xvc2VyX2xvb2sgPC0gc3Vic2V0KGFsbF9kYXRhMl9zaW5nbGVfTVIsIGFsbF9kYXRhMl9zaW5nbGVfTVIkaW1hZ2UgPT0gc3VzcGljaW91cyRpbWFnZVsyXSkKY2xvc2VyX2xvb2syIDwtIHN1YnNldChjbG9zZXJfbG9vaywgY2xvc2VyX2xvb2skcm9vdF9vcmRlciA9PSAwKQpjbG9zZXJfbG9vazIKYGBgCgpmcm9tIHRoZSBsb29rIG9mIGl0IC0gaXQgc2VlbXMgd2UgaGF2ZSB0d28gY2FzZXMgd2hlcmUgd2UgaGF2ZSBleHBvcnRlZCB0d2ljZSB0aGUgZXhhY3Qgc2FtZSByb290IGJ1dCBvbmUgbG9uZ2VyIHRoYW4gdGhlIG90aGVyIChJIHByZXN1bWUgbG9uZ2VyIGlzIGNvcnJlY3Qgb25lKS4gUHJvYmxlbSBpcyB0aGF0IHRoZWlyIHJvb3QgYW5kIGltYWdlIGFyZSBib3RoIGlkZW50aWNhbC4gCgpBZnRlciBpbnNwZWN0aW5nIHRoZSBpbWFnZXMgLSBpdCBzZWVtcyB0aGF0Ogpfc2V0MV9kYXkzXzIwMTkxMDAyXzIzOC50aWZmIGhhcyA+IDIgbGF0ZXJhbCByb290cyAKX3NldDFfZGF5M18yMDE5MTAwMl8wMDEgaGFzID4gMyBsYXRlcmFsIHJvb3RzCgpzbyBpbiBib3RoIGNhc2VzIC0gdGhlIDJuZCBNYWluIFJvb3QgaXMgYmV0dGVyLiBJIGFtIGFmZnJhaWQgdGhhdCB3ZSB3aWxsIGFsc28gZ2V0IHNvbWUgb2RkbmVzcyB3aXRoIHBvc2l0aW9ucyBvZiBsYXRlcmFsIHJvb3RzLiBTbyBtYXliZSBsZXQncyBpbnNwZWN0IGFsbCB0aGUgZGF0YSBiZWxvbmdpbmcgdG8gdGhlc2UgdHdvIGltYWdlczoKCmBgYHtyfQpvZGRfc3R1ZmYwMSA8LSBzdWJzZXQoYWxsX2RhdGEyX3NpbmdsZV9NUiwgYWxsX2RhdGEyX3NpbmdsZV9NUiRpbWFnZSA9PSAiX3NldDFfZGF5M18yMDE5MTAwMl8yMzgucnNtbCIpCm9kZF9zdHVmZjAyIDwtIHN1YnNldChhbGxfZGF0YTJfc2luZ2xlX01SLCBhbGxfZGF0YTJfc2luZ2xlX01SJGltYWdlID09ICJfc2V0MV9kYXkzXzIwMTkxMDAyXzAwMS5yc21sIikKb2RkX3N0dWZmMDEKb2RkX3N0dWZmMDIKYGBgCgpvayAtIHNvIGJhc2VkIG9uIHRoaXMgZGF0YSAtIGl0IHNlZW1zIGxpa2U6Ci0gdGhlIGZpcnN0IDMgcm93cyBpbiBvZGRfc3R1ZmYwMSBhcmUgY29udGFpbmluZyBmYXVsdHkgZGF0YSwgYW5kIHRodXMgc2hvdWxkIGJlIHJlbW92ZWQKLSB0aGUgZmlyc3QgNCByb3dzIGluIG9kZF9zdHVmZjAyIGFyZSBjb250YWluaW5nIGZhdWx0eSBkYXRhLCBhbmQgdGh1cyBzaG91bGQgYmUgcmVtb3ZlZAoKU28gbGV0J3MgcmVtb3ZlIHRoZXNlIGNvbHVtbnMgZnJvbSBpbmRpdmlkdWFsIG9kZF9zdHVmZiBmaWxlcywgcmVtb3ZlIHRoZSBlbnRpcmUgcGljdHVyZSBmcm9tIHRoZSBhbGxfZGF0YTJfc2luZ2xlX01SLCBhbmQgdGhlbiByYmluZCgpIHRoZSBvZGRfc3R1ZmYgdG9nZXRoZXIgYmFjayBpbnRvIHRoZSBhbGxfZGF0YTJfc2luZ2xlX01SOgoKYGBge3J9Cm9kZF9zdHVmZjAxIDwtIG9kZF9zdHVmZjAxWzQ6MTMsXQpvZGRfc3R1ZmYwMQoKb2RkX3N0dWZmMDIgPC0gb2RkX3N0dWZmMDJbNToxNCxdCm9kZF9zdHVmZjAyCgpieWUgPC0gYygiX3NldDFfZGF5M18yMDE5MTAwMl8yMzgucnNtbCIsICJfc2V0MV9kYXkzXzIwMTkxMDAyXzAwMS5yc21sIikKYWxsX2RhdGEzIDwtIHN1YnNldChhbGxfZGF0YTJfc2luZ2xlX01SLCAhKGFsbF9kYXRhMl9zaW5nbGVfTVIkaW1hZ2UgJWluJSBieWUpKQphbGxfZGF0YTMgPC0gcmJpbmQoYWxsX2RhdGEzLCBvZGRfc3R1ZmYwMSkKYWxsX2RhdGEzIDwtIHJiaW5kKGFsbF9kYXRhMywgb2RkX3N0dWZmMDIpCmBgYAoKTGV0J3MgZG8gYSBmaW5hbCBjaGVjayBpZiB3ZSBoYXZlIE5PIG90aGVyIGltYWdlcyB0aGF0IGhhdmUgdHdvIE1SIG5vdzoKCmBgYHtyfQpsZW5ndGgodW5pcXVlKGFsbF9kYXRhMyRpbWFnZSkpCm5hbWVzIDwtIGModGV4dD0iaW1hZ2UiLCAiTVIubm8iLCAiTFIubm8iKQpjaGVja190YWJsZTIgPC0gZGF0YS5mcmFtZSgpCgpmb3IgKGsgaW4gbmFtZXMpIGNoZWNrX3RhYmxlMltba11dIDwtIGFzLmNoYXJhY3RlcigpCgpmb3IgKGkgaW4gMTo1NTIwKSB7CiAgdW5pIDwtIHN1YnNldChhbGxfZGF0YTMsIGFsbF9kYXRhMyRpbWFnZSA9PSB1bmlxdWUoYWxsX2RhdGEzJGltYWdlKVtpXSkKICBNUiA8LSBzdWJzZXQodW5pLCB1bmkkcm9vdF9vcmRlciA9PSAwKQogIExSIDwtIHN1YnNldCh1bmksIHVuaSRyb290X29yZGVyID09IDEpCiAgCiAgY2hlY2tfdGFibGUyW2ksMV0gPC0gYXMuY2hhcmFjdGVyKHVuaXF1ZSh1bmkkaW1hZ2UpKQogIGNoZWNrX3RhYmxlMltpLDJdIDwtIGRpbShNUilbMV0KICBjaGVja190YWJsZTJbaSwzXSA8LSBkaW0oTFIpWzFdCn0KCnN1c3BpY2lvdXMgPC0gc3Vic2V0KGNoZWNrX3RhYmxlMiwgY2hlY2tfdGFibGUyJE1SLm5vID4gMSkKc3VzcGljaW91cwpgYGAKCkdyZWF0IC0gbm8gc3VzcGljaW91cyBpbWFnZXMgYW55bW9yZSAtIHNvIHdlIGNhbiBtb3ZlIG9uIDopCgojIGNhbGN1bGF0aW5nIGRlc2lyZWQgdHJhaXRzOgoKTGV0J3Mgbm93IGdldCByaWQgb2YgYWxsIHRoZSB0cmFpdHMgbGlrZSB2b2x1bWUgYW5kIGRpYW1ldGVyIHRoYXQgd2UgYXJlIG5vdCBkaXJlY3RseSBpbnRlcmVzdGVkIGluOgoKYGBge3J9CmhlYWQoYWxsX2RhdGEzKQpjb2xuYW1lcyhhbGxfZGF0YTMpCmZpbmFsIDwtIGFsbF9kYXRhM1ssYygxOjMsIDIwLCAyMiwgMjQ6MjYsIDQsIDksIDExLCAxMiwxNCwxNywxOSldCmhlYWQoZmluYWwpCmBgYAp0aGVuIC0gd2UgbmVlZCB0byBjcmVhdGUgYSBmaWxlIHRoYXQgaGFzIGFsbCBNUjoKCmBgYHtyfQpvbmx5X01SIDwtIHN1YnNldChmaW5hbCwgZmluYWwkcm9vdF9vbnRvbG9neSA9PSB1bmlxdWUoZmluYWwkcm9vdF9vbnRvbG9neSlbMV0pCmNvbG5hbWVzKG9ubHlfTVIpWzldIDwtICJNUkwiCmhlYWQob25seV9NUikKYGBgCgphbmQgc2luY2Ugd2UgZG9udCBuZWVkIHRvIGNhbGN1bGF0ZSBhbnkgTFIgcmVsYXRlZCBwaGVub3R5cGVzIGZvciB0aGUgcGxhbnRzIHRoYXQgZG9udCBoYXZlIExSIC0gd2UgbmVlZCB0byBzdWJzZXQgb3VyIE1SIGZpbGUgYSBiaXQgZnVydGhlcjoKCmBgYHtyfQpub19MUl9NUiA8LSBzdWJzZXQob25seV9NUiwgb25seV9NUiRuX2NoaWxkIDwgMSkKb25seV9NUiA8LSBzdWJzZXQob25seV9NUiwgb25seV9NUiRuX2NoaWxkID4gMCkKaGVhZChvbmx5X01SKQpoZWFkKG5vX0xSX01SKQpgYGAKCkNvb2wgLSB0aGVyZSBhcmUgbm93IHF1aXRlIGEgbG90IG9mIHVubmVjY2Vzc2FyeSBpbmZvcm1hdGlvbiBub3cgLSBzbyBsZXQncyBnZXQgdG8gYmFyZSBuZWNlc3NpdGllczoKCmBgYHtyfQpjb2xuYW1lcyhvbmx5X01SKQpvbmx5X01SIDwtIG9ubHlfTVJbLGMoMTo5LDEzOjE1KV0Kbm9fTFJfTVIgPC0gbm9fTFJfTVJbLGMoMTo5LDEzOjE1KV0KZGltKG9ubHlfTVIpCmhlYWQob25seV9NUikKYGBgCldlIGhhdmUgdGhlIHNhbWUgcm9vdCBJRCBvY2N1cnJpbmcgbXVsdGlwbGUgdGltZXMgLSBhcyB3ZSBhcmUgdHJhY2luZyBpbmRpdmlkdWFsIHBsYW50cyBhY2Nyb3NzIHRoZSB0aW1lIGFuZCB0cmFuc2ZlcnJpbmcgdGhlIGRhdGEgZnJvbSBvbmUgaW1hZ2UgdG8gYW5vdGhlciAtIHRoZXJlZm9yZSAtIGxldCdzIGNoZWNrIGlmIGl0IGFsbCBhZGRzIHVwOgoKYGBge3J9CmFsbF9NUiA8LSB1bmlxdWUob25seV9NUiRyb290KQpsZW5ndGgoYWxsX01SKQphbGxfaW1nIDwtIHVuaXF1ZShvbmx5X01SJGltYWdlKQpsZW5ndGgoYWxsX2ltZykKCmxlbmd0aChhbGxfaW1nKSAvIGxlbmd0aChhbGxfTVIpCgpvbmx5X01SJGltYWdlX2lkIDwtIHBhc3RlKG9ubHlfTVIkaW1hZ2UsICJfIiwgb25seV9NUiRyb290X25hbWUsIHNlcD0iIikKaGVhZChvbmx5X01SKQoKYWxsX2ltZ19pZCA8LSB1bmlxdWUob25seV9NUiRpbWFnZV9pZCkKbGVuZ3RoKGFsbF9pbWdfaWQpCmBgYAoKQWxtb3N0IC0gYnV0IHdlIHdpbGwgZGVhbCB3aXRoIGl0IGxhdGVyLgoKU28gd2UgaGF2ZSBpbiB0b3RhbCA0NDYwIHVuaXF1ZSBpbWFnZXMgLSB3ZSB3aWxsIGhhdmUgdG8gZXhhbWluZSB0aGUgTFIgYmVsb25naW5nIHRvIGVhY2ggTVIgaW4gZWFjaCBpbWFnZSBieSBleHRyYWN0aW5nIHRoZW0gYmFzZWQgb24gdGhlICJkYXRlIjoKCmBgYHtyfQpNUl9ub3cgPC0gYWxsX2ltZ1s0NDYwXQpNUl9ub3cKCmhlYWQoZmluYWwpCgpzdXBlcl90ZW1wIDwtIHN1YnNldChmaW5hbCwgZmluYWwkaW1hZ2UgJWluJSBNUl9ub3cpCnN1cGVyX3RlbXAKYGBgCgpUaGVuIC0gd2UgbmVlZCB0byBjcmVhdGUgc29tZSBpbmZvIGFib3V0IHRoZSBsZW5ndGggb2YgaW5kaXZpZHVhbCB6b25lcyAtIGZvciB0aGlzIHdlIG5lZWQgaW5mbyBvbiBNUl9sZW5ndGg6CgpgYGB7cn0KTVJfbGVuZ3RoIDwtIHN1YnNldChvbmx5X01SLCBvbmx5X01SJGltYWdlICVpbiUgTVJfbm93KQpNUl9sZW5ndGggPC0gTVJfbGVuZ3RoJE1STApNUl9sZW5ndGgKYGBgCgpMZW5ndGggb2YgQXBpY2FsIHpvbmUgaXMgYmFzaWNhbGx5IGVxdWFsIHRvIHBvc2l0aW9uIG9mIGZpcnN0IGxhdGVyYWwgcm9vdCBCcmFuY2hlZCB6b25lIGxlbmd0aCBpcyB0aGUgcG9zaXRpb24gb2YgbGFzdCBMUiAtIHBvc2l0aW9uIG9mIGZpcnN0IExSIEJhc2FsIHpvbmUgaXMgdGhlIE1SIGxlbmd0aCAtIHBvc2l0aW9uIG9mIGxhc3QgTFIgdGh1czoKCmBgYHtyfQpzdXBlcl90ZW1wIDwtIHN1YnNldChzdXBlcl90ZW1wLCBzdXBlcl90ZW1wJHJvb3Rfb250b2xvZ3kgPT0gdW5pcXVlKHN1cGVyX3RlbXAkcm9vdF9vbnRvbG9neSlbMl0pCnN1cGVyX3RlbXAKQXBpY2FsIDwtIG1pbihzdXBlcl90ZW1wJGluc2VydGlvbl9wb3NpdGlvbikKQnJhbmNoZWQgPC0gKG1heChzdXBlcl90ZW1wJGluc2VydGlvbl9wb3NpdGlvbikgLSBBcGljYWwpCkJhc2FsIDwtIE1SX2xlbmd0aCAtIG1heChzdXBlcl90ZW1wJGluc2VydGlvbl9wb3NpdGlvbikKQXBpY2FsCkJyYW5jaGVkCkJhc2FsCmBgYAoKQW5vdGhlciB0aGluZyB0aGF0IEkgYW0gaW50ZXJlc3RlZCBpbiBpcyB0aGUgZGlzdHJpYnV0aW9uIG9mIExSTCBhY3Jvc3MgdGhlIE1SIGFuZCBob3cgcXVpY2tseSB0aGF0IGRlY3JlYXNlcyBhY3Jvc3MgdGhlIE1STAoKYGBge3J9CnN1cGVyX3RlbXAKI3N1cGVyX3RlbXAkYWRqX3Bvc2l0aW9uIDwtIHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uICsgMC4wMDAwMDAxCnBsb3Qoc3VwZXJfdGVtcCRsZW5ndGggfiBzdXBlcl90ZW1wJGluc2VydGlvbl9wb3NpdGlvbikKYWJsaW5lKGxtKHN1cGVyX3RlbXAkbGVuZ3RoIH4gc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb24pKQptb2RlbCA8LSBsbShzdXBlcl90ZW1wJGxlbmd0aCB+IHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uKQpzdW1tYXJ5KG1vZGVsKQptb2RlbCRjb2VmZmljaWVudHMKTFJMLmRlYyA8LSBtb2RlbCRjb2VmZmljaWVudHNbWzJdXQpMUkwuZGVjLlIyIDwtIHN1bW1hcnkobW9kZWwpJHIuc3F1YXJlZApMUkwuZGVjLlIyCkxSTC5kZWMKYGBgCgoKVGhlbiAtIHdlIGNhbiBjYWxjdWxhdGUgdGhlICUgb2YgTFIgYWNyb3NzIHRoZSBNUiBsZW5ndGggLSBieSBkaXZpZGluZyB0aGUgTVIgaW50byA0IG9yIDEwIHBhcnRzCgpgYGB7cn0Kc3VwZXJfdGVtcCRMUl9pbl8xMF9wZXJjIDwtIDAKc3VwZXJfdGVtcCRMUl9pbl8yMF9wZXJjIDwtIDAKc3VwZXJfdGVtcCRMUl9pbl8zMF9wZXJjIDwtIDAKc3VwZXJfdGVtcCRMUl9pbl80MF9wZXJjIDwtIDAKc3VwZXJfdGVtcCRMUl9pbl81MF9wZXJjIDwtIDAKc3VwZXJfdGVtcCRMUl9pbl82MF9wZXJjIDwtIDAKc3VwZXJfdGVtcCRMUl9pbl83MF9wZXJjIDwtIDAKc3VwZXJfdGVtcCRMUl9pbl84MF9wZXJjIDwtIDAKc3VwZXJfdGVtcCRMUl9pbl85MF9wZXJjIDwtIDAKc3VwZXJfdGVtcCRMUl9pbl8xMDBfcGVyYyA8LSAwCgoKZm9yKGUgaW4gMTpucm93KHN1cGVyX3RlbXApKXsKICAgaWYgKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdIDwgKE1SX2xlbmd0aC8xMCkpewogICAgc3VwZXJfdGVtcCRMUl9pbl8xMF9wZXJjW2VdIDwtIDEKICAgfSBlbHNlIHtzdXBlcl90ZW1wJExSX2luXzEwX3BlcmNbZV0gPC0gMH0KICBpZiAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPCAyKihNUl9sZW5ndGgvMTApICYgc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPiAoTVJfbGVuZ3RoLzEwKSl7CiAgICBzdXBlcl90ZW1wJExSX2luXzIwX3BlcmNbZV0gPC0gMQogIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl8yMF9wZXJjW2VdIDwtIDB9CiAgaWYgKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdIDwgMyooTVJfbGVuZ3RoLzEwKSAmIHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdID4gMiooTVJfbGVuZ3RoLzEwKSl7CiAgICBzdXBlcl90ZW1wJExSX2luXzMwX3BlcmNbZV0gPC0gMQogIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl8zMF9wZXJjW2VdIDwtIDB9CiAgaWYgKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdIDwgNCooTVJfbGVuZ3RoLzEwKSAmIHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdID4gMyooTVJfbGVuZ3RoLzEwKSl7CiAgICBzdXBlcl90ZW1wJExSX2luXzQwX3BlcmNbZV0gPC0gMQogIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl80MF9wZXJjW2VdIDwtIDB9CiAgaWYgKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdIDwgNSooTVJfbGVuZ3RoLzEwKSAmIHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdID4gNCooTVJfbGVuZ3RoLzEwKSl7CiAgICBzdXBlcl90ZW1wJExSX2luXzUwX3BlcmNbZV0gPC0gMQogIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl81MF9wZXJjW2VdIDwtIDB9CiAgaWYgKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdIDwgNiooTVJfbGVuZ3RoLzEwKSAmIHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdID4gNSooTVJfbGVuZ3RoLzEwKSl7CiAgICBzdXBlcl90ZW1wJExSX2luXzYwX3BlcmNbZV0gPC0gMQogIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl82MF9wZXJjW2VdIDwtIDB9CiAgaWYgKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdIDwgNyooTVJfbGVuZ3RoLzEwKSAmIHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdID4gNiooTVJfbGVuZ3RoLzEwKSl7CiAgICBzdXBlcl90ZW1wJExSX2luXzcwX3BlcmNbZV0gPC0gMQogIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl83MF9wZXJjW2VdIDwtIDB9CiAgaWYgKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdIDwgOCooTVJfbGVuZ3RoLzEwKSAmIHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdID4gNyooTVJfbGVuZ3RoLzEwKSl7CiAgICBzdXBlcl90ZW1wJExSX2luXzgwX3BlcmNbZV0gPC0gMQogIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl84MF9wZXJjW2VdIDwtIDB9CiAgaWYgKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdIDwgOSooTVJfbGVuZ3RoLzEwKSAmIHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdID4gOCooTVJfbGVuZ3RoLzEwKSl7CiAgICBzdXBlcl90ZW1wJExSX2luXzkwX3BlcmNbZV0gPC0gMQogIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl85MF9wZXJjW2VdIDwtIDB9CiAgaWYgKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdIDwgMTAqKE1SX2xlbmd0aC8xMCkgJiBzdXBlcl90ZW1wJGluc2VydGlvbl9wb3NpdGlvbltlXSA+IDkqKE1SX2xlbmd0aC8xMCkpewogICAgc3VwZXJfdGVtcCRMUl9pbl8xMDBfcGVyY1tlXSA8LSAxCiAgfSBlbHNlIHtzdXBlcl90ZW1wJExSX2luXzEwMF9wZXJjW2VdIDwtIDB9Cn0KCnN1cGVyX3RlbXAKYGBgCgpzbyBhZnRlciBjbGFzc2lmeWluZyBlYWNoIExSIHRvIGl0cyByZXNwZWN0aXZlIHBvcnRpb24gb2YgTVIsIHdlIGNhbiB0aGVuIHN1bW1hcml6ZSB0aGVtIGFuZCBjYWxjdWxhdGUgdG90YWwgTFIgbGVuZ3RoIGluIHRoaXMgZnJhZ21lbnQ6CgpgYGB7cn0Kc3VwZXJfdGVtcCRMUkxfaW5fMTBfcGVyYyA8LSBzdXBlcl90ZW1wJGxlbmd0aCAqIHN1cGVyX3RlbXAkTFJfaW5fMTBfcGVyYwpzdXBlcl90ZW1wJExSTF9pbl8yMF9wZXJjIDwtIHN1cGVyX3RlbXAkbGVuZ3RoICogc3VwZXJfdGVtcCRMUl9pbl8yMF9wZXJjCnN1cGVyX3RlbXAkTFJMX2luXzMwX3BlcmMgPC0gc3VwZXJfdGVtcCRsZW5ndGggKiBzdXBlcl90ZW1wJExSX2luXzMwX3BlcmMKc3VwZXJfdGVtcCRMUkxfaW5fNDBfcGVyYyA8LSBzdXBlcl90ZW1wJGxlbmd0aCAqIHN1cGVyX3RlbXAkTFJfaW5fNDBfcGVyYwpzdXBlcl90ZW1wJExSTF9pbl81MF9wZXJjIDwtIHN1cGVyX3RlbXAkbGVuZ3RoICogc3VwZXJfdGVtcCRMUl9pbl81MF9wZXJjCnN1cGVyX3RlbXAkTFJMX2luXzYwX3BlcmMgPC0gc3VwZXJfdGVtcCRsZW5ndGggKiBzdXBlcl90ZW1wJExSX2luXzYwX3BlcmMKc3VwZXJfdGVtcCRMUkxfaW5fNzBfcGVyYyA8LSBzdXBlcl90ZW1wJGxlbmd0aCAqIHN1cGVyX3RlbXAkTFJfaW5fNzBfcGVyYwpzdXBlcl90ZW1wJExSTF9pbl84MF9wZXJjIDwtIHN1cGVyX3RlbXAkbGVuZ3RoICogc3VwZXJfdGVtcCRMUl9pbl84MF9wZXJjCnN1cGVyX3RlbXAkTFJMX2luXzkwX3BlcmMgPC0gc3VwZXJfdGVtcCRsZW5ndGggKiBzdXBlcl90ZW1wJExSX2luXzkwX3BlcmMKc3VwZXJfdGVtcCRMUkxfaW5fMTAwX3BlcmMgPC0gc3VwZXJfdGVtcCRsZW5ndGggKiBzdXBlcl90ZW1wJExSX2luXzEwMF9wZXJjCgpMUl9ub18xMF8xMDAgPC0gc3VtKHN1cGVyX3RlbXAkTFJfaW5fMTBfcGVyYykKTFJfbm9fMjBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzIwX3BlcmMpCkxSX25vXzMwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUl9pbl8zMF9wZXJjKQpMUl9ub180MF8xMDAgPC0gc3VtKHN1cGVyX3RlbXAkTFJfaW5fNDBfcGVyYykKTFJfbm9fNTBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzUwX3BlcmMpCkxSX25vXzYwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUl9pbl82MF9wZXJjKQpMUl9ub183MF8xMDAgPC0gc3VtKHN1cGVyX3RlbXAkTFJfaW5fNzBfcGVyYykKTFJfbm9fODBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzgwX3BlcmMpCkxSX25vXzkwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUl9pbl85MF9wZXJjKQpMUl9ub18xMDBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzEwMF9wZXJjKQoKTFJMXzEwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fMTBfcGVyYykKTFJMXzIwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fMjBfcGVyYykKTFJMXzMwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fMzBfcGVyYykKTFJMXzQwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fNDBfcGVyYykKTFJMXzUwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fNTBfcGVyYykKTFJMXzYwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fNjBfcGVyYykKTFJMXzcwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fNzBfcGVyYykKTFJMXzgwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fODBfcGVyYykKTFJMXzkwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fOTBfcGVyYykKTFJMXzEwMF8xMDAgPC0gc3VtKHN1cGVyX3RlbXAkTFJMX2luXzEwMF9wZXJjKQpgYGAKCk9LIC0gbGFzdCBidXQgbm90IGxlYXN0IC0gd2Ugc2hvdWxkIGNhbGN1bGF0ZSB0aGUgY2VudGVyIG9mIGdyYXZpdHkgZm9yIExSOgoKYGBge3J9CnN1cGVyX3RlbXAkbW9tZW50dW0gPC0gKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uICogc3VwZXJfdGVtcCRsZW5ndGgpCmFsbF9tb21lbnR1bSA8LSBzdW0oc3VwZXJfdGVtcCRtb21lbnR1bSkKYWxsX21vbWVudHVtCmFsbF9sZW5ndGggPC0gc3VtKHN1cGVyX3RlbXAkbGVuZ3RoKQphbGxfbGVuZ3RoCkNvRyA8LSAoYWxsX21vbWVudHVtIC8gYWxsX2xlbmd0aCkKQ29HCmBgYAoKRmluYWxseSAtIGxldOKAmXMgYWRkIGFsbCB0aGVzZSB2YWx1ZXMgaW50byBvdXIgTVJfb25seSB0YWJsZQoKRmlyc3Qgd2UgbmVlZCB0byBjcmVhdGUgbmVlZGVkIGNvbHVtbnM6CmBgYHtyfQpvbmx5X01SJEFwaWNhbCA8LSAwCm9ubHlfTVIkQnJhbmNoZWQgPC0gMApvbmx5X01SJEJhc2FsIDwtIDAKCm9ubHlfTVIkQXBpY2FsX3BlcmMgPC0gMApvbmx5X01SJEJyYW5jaGVkX3BlcmMgPC0gMApvbmx5X01SJEJhc2FsX3BlcmMgPC0gMApvbmx5X01SJExSX25vXzEwXzEwMCA8LSAwCm9ubHlfTVIkTFJfbm9fMjBfMTAwIDwtIDAKb25seV9NUiRMUl9ub18zMF8xMDAgPC0gMApvbmx5X01SJExSX25vXzQwXzEwMCA8LSAwCm9ubHlfTVIkTFJfbm9fNTBfMTAwIDwtIDAKb25seV9NUiRMUl9ub182MF8xMDAgPC0gMApvbmx5X01SJExSX25vXzcwXzEwMCA8LSAwCm9ubHlfTVIkTFJfbm9fODBfMTAwIDwtIDAKb25seV9NUiRMUl9ub185MF8xMDAgPC0gMApvbmx5X01SJExSX25vXzEwMF8xMDAgPC0gMAoKb25seV9NUiRMUkxfMTBfMTAwIDwtIDAKb25seV9NUiRMUkxfMjBfMTAwIDwtIDAKb25seV9NUiRMUkxfMzBfMTAwIDwtIDAKb25seV9NUiRMUkxfNDBfMTAwIDwtIDAKb25seV9NUiRMUkxfNTBfMTAwIDwtIDAKb25seV9NUiRMUkxfNjBfMTAwIDwtIDAKb25seV9NUiRMUkxfNzBfMTAwIDwtIDAKb25seV9NUiRMUkxfODBfMTAwIDwtIDAKb25seV9NUiRMUkxfOTBfMTAwIDwtIDAKb25seV9NUiRMUkxfMTAwXzEwMCA8LSAwCgpvbmx5X01SJENvRyA8LSAwCm9ubHlfTVIkTFJMLmRlYyA8LSAwCm9ubHlfTVIkTFJMLmRlYy5SMiA8LSAwCmhlYWQob25seV9NUikKYGBgCgp0aGVuIGFkZCB2YWx1ZXMgdG8gdGhlc2UgY29sdW1uczoKCmBgYHtyfQpvbmx5X01SJEFwaWNhbFsxXSA8LSBBcGljYWwKb25seV9NUiRCcmFuY2hlZFsxXSA8LSBCcmFuY2hlZApvbmx5X01SJEJhc2FsWzFdIDwtIEJhc2FsCgpvbmx5X01SJEFwaWNhbF9wZXJjWzFdIDwtIChBcGljYWwgLyBNUl9sZW5ndGgpCm9ubHlfTVIkQnJhbmNoZWRfcGVyY1sxXSA8LSAoQnJhbmNoZWQgLyBNUl9sZW5ndGgpCm9ubHlfTVIkQmFzYWxfcGVyY1sxXSA8LSAoQmFzYWwgLyBNUl9sZW5ndGgpCm9ubHlfTVIkTFJfbm9fMTBfMTAwWzFdIDwtIExSX25vXzEwXzEwMApvbmx5X01SJExSX25vXzIwXzEwMFsxXSA8LSBMUl9ub18yMF8xMDAKb25seV9NUiRMUl9ub18zMF8xMDBbMV0gPC0gTFJfbm9fMzBfMTAwCm9ubHlfTVIkTFJfbm9fNDBfMTAwWzFdIDwtIExSX25vXzQwXzEwMApvbmx5X01SJExSX25vXzUwXzEwMFsxXSA8LSBMUl9ub181MF8xMDAKb25seV9NUiRMUl9ub182MF8xMDBbMV0gPC0gTFJfbm9fNjBfMTAwCm9ubHlfTVIkTFJfbm9fNzBfMTAwWzFdIDwtIExSX25vXzcwXzEwMApvbmx5X01SJExSX25vXzgwXzEwMFsxXSA8LSBMUl9ub184MF8xMDAKb25seV9NUiRMUl9ub185MF8xMDBbMV0gPC0gTFJfbm9fOTBfMTAwCm9ubHlfTVIkTFJfbm9fMTAwXzEwMFsxXSA8LSBMUl9ub18xMDBfMTAwCgpvbmx5X01SJExSTF8xMF8xMDBbMV0gPC0gTFJMXzEwXzEwMApvbmx5X01SJExSTF8yMF8xMDBbMV0gPC0gTFJMXzIwXzEwMApvbmx5X01SJExSTF8zMF8xMDBbMV0gPC0gTFJMXzMwXzEwMApvbmx5X01SJExSTF80MF8xMDBbMV0gPC0gTFJMXzQwXzEwMApvbmx5X01SJExSTF81MF8xMDBbMV0gPC0gTFJMXzUwXzEwMApvbmx5X01SJExSTF82MF8xMDBbMV0gPC0gTFJMXzYwXzEwMApvbmx5X01SJExSTF83MF8xMDBbMV0gPC0gTFJMXzcwXzEwMApvbmx5X01SJExSTF84MF8xMDBbMV0gPC0gTFJMXzgwXzEwMApvbmx5X01SJExSTF85MF8xMDBbMV0gPC0gTFJMXzkwXzEwMApvbmx5X01SJExSTF8xMDBfMTAwWzFdIDwtIExSTF8xMDBfMTAwCgpvbmx5X01SJENvR1sxXSA8LSBDb0cKCm9ubHlfTVIkTFJMLmRlY1sxXSA8LSBMUkwuZGVjCm9ubHlfTVIkTFJMLmRlYy5SMlsxXSA8LSBMUkwuZGVjLlIyICAKCmhlYWQob25seV9NUikKYGBgCmNvb2wgLSBsb29rcyBnb29kLiBMZXQncyBsb29wIGl0OgoKCmBgYHtyfQpkaW0oZmluYWwpCmxlbmd0aChhbGxfaW1nKQpgYGAKCmBgYHtyfQpmb3IoaSBpbiBjKDI6NDQ2MCkpewogIE1SX25vdyA8LSBhbGxfaW1nW2ldCiAgc3VwZXJfdGVtcCA8LSBzdWJzZXQoZmluYWwsIGZpbmFsJGltYWdlICVpbiUgTVJfbm93KQogIE1SX2xlbmd0aCA8LSBzdWJzZXQob25seV9NUiwgb25seV9NUiRpbWFnZSAlaW4lIE1SX25vdykKICBNUl9sZW5ndGggPC0gTVJfbGVuZ3RoJE1STAogIHN1cGVyX3RlbXAgPC0gc3Vic2V0KHN1cGVyX3RlbXAsIHN1cGVyX3RlbXAkcm9vdF9vbnRvbG9neSA9PSB1bmlxdWUoc3VwZXJfdGVtcCRyb290X29udG9sb2d5KVsyXSkKICBBcGljYWwgPC0gbWluKHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uKQogIEJyYW5jaGVkIDwtIChtYXgoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb24pIC0gQXBpY2FsKQogIEJhc2FsIDwtIE1SX2xlbmd0aCAtIG1heChzdXBlcl90ZW1wJGluc2VydGlvbl9wb3NpdGlvbikKICAKICBzdXBlcl90ZW1wJExSX2luXzEwX3BlcmMgPC0gMAogIHN1cGVyX3RlbXAkTFJfaW5fMjBfcGVyYyA8LSAwCiAgc3VwZXJfdGVtcCRMUl9pbl8zMF9wZXJjIDwtIDAKICBzdXBlcl90ZW1wJExSX2luXzQwX3BlcmMgPC0gMAogIHN1cGVyX3RlbXAkTFJfaW5fNTBfcGVyYyA8LSAwCiAgc3VwZXJfdGVtcCRMUl9pbl82MF9wZXJjIDwtIDAKICBzdXBlcl90ZW1wJExSX2luXzcwX3BlcmMgPC0gMAogIHN1cGVyX3RlbXAkTFJfaW5fODBfcGVyYyA8LSAwCiAgc3VwZXJfdGVtcCRMUl9pbl85MF9wZXJjIDwtIDAKICBzdXBlcl90ZW1wJExSX2luXzEwMF9wZXJjIDwtIDAKCiAgZm9yKGUgaW4gMTpucm93KHN1cGVyX3RlbXApKXsKICAgICBpZiAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPCAoTVJfbGVuZ3RoLzEwKSl7CiAgICAgIHN1cGVyX3RlbXAkTFJfaW5fMTBfcGVyY1tlXSA8LSAxCiAgICAgfSBlbHNlIHtzdXBlcl90ZW1wJExSX2luXzEwX3BlcmNbZV0gPC0gMH0KICAgIGlmIChzdXBlcl90ZW1wJGluc2VydGlvbl9wb3NpdGlvbltlXSA8IDIqKE1SX2xlbmd0aC8xMCkgJiBzdXBlcl90ZW1wJGluc2VydGlvbl9wb3NpdGlvbltlXSA+IChNUl9sZW5ndGgvMTApKXsKICAgICAgc3VwZXJfdGVtcCRMUl9pbl8yMF9wZXJjW2VdIDwtIDEKICAgIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl8yMF9wZXJjW2VdIDwtIDB9CiAgICBpZiAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPCAzKihNUl9sZW5ndGgvMTApICYgc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPiAyKihNUl9sZW5ndGgvMTApKXsKICAgICAgc3VwZXJfdGVtcCRMUl9pbl8zMF9wZXJjW2VdIDwtIDEKICAgIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl8zMF9wZXJjW2VdIDwtIDB9CiAgICBpZiAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPCA0KihNUl9sZW5ndGgvMTApICYgc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPiAzKihNUl9sZW5ndGgvMTApKXsKICAgICAgc3VwZXJfdGVtcCRMUl9pbl80MF9wZXJjW2VdIDwtIDEKICAgIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl80MF9wZXJjW2VdIDwtIDB9CiAgICBpZiAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPCA1KihNUl9sZW5ndGgvMTApICYgc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPiA0KihNUl9sZW5ndGgvMTApKXsKICAgICAgc3VwZXJfdGVtcCRMUl9pbl81MF9wZXJjW2VdIDwtIDEKICAgIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl81MF9wZXJjW2VdIDwtIDB9CiAgICBpZiAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPCA2KihNUl9sZW5ndGgvMTApICYgc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPiA1KihNUl9sZW5ndGgvMTApKXsKICAgICAgc3VwZXJfdGVtcCRMUl9pbl82MF9wZXJjW2VdIDwtIDEKICAgIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl82MF9wZXJjW2VdIDwtIDB9CiAgICBpZiAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPCA3KihNUl9sZW5ndGgvMTApICYgc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPiA2KihNUl9sZW5ndGgvMTApKXsKICAgICAgc3VwZXJfdGVtcCRMUl9pbl83MF9wZXJjW2VdIDwtIDEKICAgIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl83MF9wZXJjW2VdIDwtIDB9CiAgICBpZiAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPCA4KihNUl9sZW5ndGgvMTApICYgc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPiA3KihNUl9sZW5ndGgvMTApKXsKICAgICAgc3VwZXJfdGVtcCRMUl9pbl84MF9wZXJjW2VdIDwtIDEKICAgIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl84MF9wZXJjW2VdIDwtIDB9CiAgICBpZiAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPCA5KihNUl9sZW5ndGgvMTApICYgc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPiA4KihNUl9sZW5ndGgvMTApKXsKICAgICAgc3VwZXJfdGVtcCRMUl9pbl85MF9wZXJjW2VdIDwtIDEKICAgIH0gZWxzZSB7c3VwZXJfdGVtcCRMUl9pbl85MF9wZXJjW2VdIDwtIDB9CiAgICBpZiAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb25bZV0gPCAxMCooTVJfbGVuZ3RoLzEwKSAmIHN1cGVyX3RlbXAkaW5zZXJ0aW9uX3Bvc2l0aW9uW2VdID4gOSooTVJfbGVuZ3RoLzEwKSl7CiAgICAgIHN1cGVyX3RlbXAkTFJfaW5fMTAwX3BlcmNbZV0gPC0gMQogICAgfSBlbHNlIHtzdXBlcl90ZW1wJExSX2luXzEwMF9wZXJjW2VdIDwtIDB9CiAgfSAKCiAgc3VwZXJfdGVtcCRMUkxfaW5fMTBfcGVyYyA8LSBzdXBlcl90ZW1wJGxlbmd0aCAqIHN1cGVyX3RlbXAkTFJfaW5fMTBfcGVyYwogIHN1cGVyX3RlbXAkTFJMX2luXzIwX3BlcmMgPC0gc3VwZXJfdGVtcCRsZW5ndGggKiBzdXBlcl90ZW1wJExSX2luXzIwX3BlcmMKICBzdXBlcl90ZW1wJExSTF9pbl8zMF9wZXJjIDwtIHN1cGVyX3RlbXAkbGVuZ3RoICogc3VwZXJfdGVtcCRMUl9pbl8zMF9wZXJjCiAgc3VwZXJfdGVtcCRMUkxfaW5fNDBfcGVyYyA8LSBzdXBlcl90ZW1wJGxlbmd0aCAqIHN1cGVyX3RlbXAkTFJfaW5fNDBfcGVyYwogIHN1cGVyX3RlbXAkTFJMX2luXzUwX3BlcmMgPC0gc3VwZXJfdGVtcCRsZW5ndGggKiBzdXBlcl90ZW1wJExSX2luXzUwX3BlcmMKICBzdXBlcl90ZW1wJExSTF9pbl82MF9wZXJjIDwtIHN1cGVyX3RlbXAkbGVuZ3RoICogc3VwZXJfdGVtcCRMUl9pbl82MF9wZXJjCiAgc3VwZXJfdGVtcCRMUkxfaW5fNzBfcGVyYyA8LSBzdXBlcl90ZW1wJGxlbmd0aCAqIHN1cGVyX3RlbXAkTFJfaW5fNzBfcGVyYwogIHN1cGVyX3RlbXAkTFJMX2luXzgwX3BlcmMgPC0gc3VwZXJfdGVtcCRsZW5ndGggKiBzdXBlcl90ZW1wJExSX2luXzgwX3BlcmMKICBzdXBlcl90ZW1wJExSTF9pbl85MF9wZXJjIDwtIHN1cGVyX3RlbXAkbGVuZ3RoICogc3VwZXJfdGVtcCRMUl9pbl85MF9wZXJjCiAgc3VwZXJfdGVtcCRMUkxfaW5fMTAwX3BlcmMgPC0gc3VwZXJfdGVtcCRsZW5ndGggKiBzdXBlcl90ZW1wJExSX2luXzEwMF9wZXJjCiAgCiAgTFJfbm9fMTBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzEwX3BlcmMpCiAgTFJfbm9fMjBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzIwX3BlcmMpCiAgTFJfbm9fMzBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzMwX3BlcmMpCiAgTFJfbm9fNDBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzQwX3BlcmMpCiAgTFJfbm9fNTBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzUwX3BlcmMpCiAgTFJfbm9fNjBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzYwX3BlcmMpCiAgTFJfbm9fNzBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzcwX3BlcmMpCiAgTFJfbm9fODBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzgwX3BlcmMpCiAgTFJfbm9fOTBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSX2luXzkwX3BlcmMpCiAgTFJfbm9fMTAwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUl9pbl8xMDBfcGVyYykKICAKICBMUkxfMTBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSTF9pbl8xMF9wZXJjKQogIExSTF8yMF8xMDAgPC0gc3VtKHN1cGVyX3RlbXAkTFJMX2luXzIwX3BlcmMpCiAgTFJMXzMwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fMzBfcGVyYykKICBMUkxfNDBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSTF9pbl80MF9wZXJjKQogIExSTF81MF8xMDAgPC0gc3VtKHN1cGVyX3RlbXAkTFJMX2luXzUwX3BlcmMpCiAgTFJMXzYwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fNjBfcGVyYykKICBMUkxfNzBfMTAwIDwtIHN1bShzdXBlcl90ZW1wJExSTF9pbl83MF9wZXJjKQogIExSTF84MF8xMDAgPC0gc3VtKHN1cGVyX3RlbXAkTFJMX2luXzgwX3BlcmMpCiAgTFJMXzkwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fOTBfcGVyYykKICBMUkxfMTAwXzEwMCA8LSBzdW0oc3VwZXJfdGVtcCRMUkxfaW5fMTAwX3BlcmMpCiAgCiAgc3VwZXJfdGVtcCRtb21lbnR1bSA8LSAoc3VwZXJfdGVtcCRpbnNlcnRpb25fcG9zaXRpb24gKiBzdXBlcl90ZW1wJGxlbmd0aCkKICBhbGxfbW9tZW50dW0gPC0gc3VtKHN1cGVyX3RlbXAkbW9tZW50dW0pCiAgYWxsX2xlbmd0aCA8LSBzdW0oc3VwZXJfdGVtcCRsZW5ndGgpCiAgQ29HIDwtIChhbGxfbW9tZW50dW0gLyBhbGxfbGVuZ3RoKSAgCiAgCiAgaWYoZGltKHN1cGVyX3RlbXApWzFdID4gMil7CiAgbW9kZWwgPC0gbG0oc3VwZXJfdGVtcCRsZW5ndGggfiBzdXBlcl90ZW1wJGluc2VydGlvbl9wb3NpdGlvbikKICBMUkwuZGVjIDwtIG1vZGVsJGNvZWZmaWNpZW50c1tbMl1dCiAgTFJMLmRlYy5SMiA8LSBzdW1tYXJ5KG1vZGVsKSRyLnNxdWFyZWQKICB9IGVsc2UgewogICAgTFJMLmRlYyA8LSAibi5hLiIKICAgIExSTC5kZWMuUjIgPC0gIm4uYS4iCiAgfQogIAogIAogIG9ubHlfTVIkQXBpY2FsW2ldIDwtIEFwaWNhbAogIG9ubHlfTVIkQnJhbmNoZWRbaV0gPC0gQnJhbmNoZWQKICBvbmx5X01SJEJhc2FsW2ldIDwtIEJhc2FsCiAgCiAgb25seV9NUiRBcGljYWxfcGVyY1tpXSA8LSAoQXBpY2FsIC8gTVJfbGVuZ3RoKQogIG9ubHlfTVIkQnJhbmNoZWRfcGVyY1tpXSA8LSAoQnJhbmNoZWQgLyBNUl9sZW5ndGgpCiAgb25seV9NUiRCYXNhbF9wZXJjW2ldIDwtIChCYXNhbCAvIE1SX2xlbmd0aCkKICBvbmx5X01SJExSX25vXzEwXzEwMFtpXSA8LSBMUl9ub18xMF8xMDAKICBvbmx5X01SJExSX25vXzIwXzEwMFtpXSA8LSBMUl9ub18yMF8xMDAKICBvbmx5X01SJExSX25vXzMwXzEwMFtpXSA8LSBMUl9ub18zMF8xMDAKICBvbmx5X01SJExSX25vXzQwXzEwMFtpXSA8LSBMUl9ub180MF8xMDAKICBvbmx5X01SJExSX25vXzUwXzEwMFtpXSA8LSBMUl9ub181MF8xMDAKICBvbmx5X01SJExSX25vXzYwXzEwMFtpXSA8LSBMUl9ub182MF8xMDAKICBvbmx5X01SJExSX25vXzcwXzEwMFtpXSA8LSBMUl9ub183MF8xMDAKICBvbmx5X01SJExSX25vXzgwXzEwMFtpXSA8LSBMUl9ub184MF8xMDAKICBvbmx5X01SJExSX25vXzkwXzEwMFtpXSA8LSBMUl9ub185MF8xMDAKICBvbmx5X01SJExSX25vXzEwMF8xMDBbaV0gPC0gTFJfbm9fMTAwXzEwMAogIAogIG9ubHlfTVIkTFJMXzEwXzEwMFtpXSA8LSBMUkxfMTBfMTAwCiAgb25seV9NUiRMUkxfMjBfMTAwW2ldIDwtIExSTF8yMF8xMDAKICBvbmx5X01SJExSTF8zMF8xMDBbaV0gPC0gTFJMXzMwXzEwMAogIG9ubHlfTVIkTFJMXzQwXzEwMFtpXSA8LSBMUkxfNDBfMTAwCiAgb25seV9NUiRMUkxfNTBfMTAwW2ldIDwtIExSTF81MF8xMDAKICBvbmx5X01SJExSTF82MF8xMDBbaV0gPC0gTFJMXzYwXzEwMAogIG9ubHlfTVIkTFJMXzcwXzEwMFtpXSA8LSBMUkxfNzBfMTAwCiAgb25seV9NUiRMUkxfODBfMTAwW2ldIDwtIExSTF84MF8xMDAKICBvbmx5X01SJExSTF85MF8xMDBbaV0gPC0gTFJMXzkwXzEwMAogIG9ubHlfTVIkTFJMXzEwMF8xMDBbaV0gPC0gTFJMXzEwMF8xMDAKICAKICBvbmx5X01SJENvR1tpXSA8LSBDb0cKICBvbmx5X01SJExSTC5kZWNbaV0gPC0gTFJMLmRlYwogIG9ubHlfTVIkTFJMLmRlYy5SMltpXSA8LSBMUkwuZGVjLlIyICAKfQoKYGBgCgpsZXQncyBoYXZlIGEgbG9vayBhdCB0aGUgZW50aXJlIHRhYmxlOgoKYGBge3J9CmhlYWQob25seV9NUikKdGFpbChvbmx5X01SKQpgYGAKCnRoZW4tIHdlIG5lZWQgdG8gZnVzZSBhbGwgdGhlIG1haW4gcm9vdHMgdGhhdCBkb250IG93biBMUgoKTWFrZSBzdXJlIHRoYXQgdGhlIGRhdGEgc3RydWN0dXJlIGlzIHRoZSBzYW1lIGFzIGZvciB0aGUgb25seV9NUiBmaWxlCgpgYGB7cn0KaGVhZChub19MUl9NUikKYGBgCmxldCdzIGFkZCBtaXNzaW5nIGNvbGx1bW5zOgoKYGBge3J9Cm5vX0xSX01SJEFwaWNhbCA8LSAibi5hLiIKbm9fTFJfTVIkQnJhbmNoZWQgPC0gIm4uYS4iCm5vX0xSX01SJEJhc2FsIDwtICJuLmEuIgoKbm9fTFJfTVIkQXBpY2FsX3BlcmMgPC0gIm4uYS4iCm5vX0xSX01SJEJyYW5jaGVkX3BlcmMgPC0gIm4uYS4iCm5vX0xSX01SJEJhc2FsX3BlcmMgPC0gIm4uYS4iCgpub19MUl9NUiRMUl9ub18xMF8xMDAgPC0gMApub19MUl9NUiRMUl9ub18yMF8xMDAgPC0gMApub19MUl9NUiRMUl9ub18zMF8xMDAgPC0gMApub19MUl9NUiRMUl9ub180MF8xMDAgPC0gMApub19MUl9NUiRMUl9ub181MF8xMDAgPC0gMApub19MUl9NUiRMUl9ub182MF8xMDAgPC0gMApub19MUl9NUiRMUl9ub183MF8xMDAgPC0gMApub19MUl9NUiRMUl9ub184MF8xMDAgPC0gMApub19MUl9NUiRMUl9ub185MF8xMDAgPC0gMApub19MUl9NUiRMUl9ub18xMDBfMTAwIDwtIDAKCm5vX0xSX01SJExSTF8xMF8xMDAgPC0gMApub19MUl9NUiRMUkxfMjBfMTAwIDwtIDAKbm9fTFJfTVIkTFJMXzMwXzEwMCA8LSAwCm5vX0xSX01SJExSTF80MF8xMDAgPC0gMApub19MUl9NUiRMUkxfNTBfMTAwIDwtIDAKbm9fTFJfTVIkTFJMXzYwXzEwMCA8LSAwCm5vX0xSX01SJExSTF83MF8xMDAgPC0gMApub19MUl9NUiRMUkxfODBfMTAwIDwtIDAKbm9fTFJfTVIkTFJMXzkwXzEwMCA8LSAwCm5vX0xSX01SJExSTF8xMDBfMTAwIDwtIDAKCm5vX0xSX01SJENvRyA8LSAwCm5vX0xSX01SJExSTC5kZWMgPC0gIm4uYS4iCm5vX0xSX01SJExSTC5kZWMuUjIgPC0gIm4uYS4iCmBgYAoKZmluYWxseSAtIGxldOKAmXMgZnVzZSB0aGUgdHdvIGZpbGVzIHRvZ2V0aGVyOgoKCmBgYHtyfQpjb2xuYW1lcyhvbmx5X01SKQpjb2xuYW1lcyhub19MUl9NUikKCm9ubHlfTVIgPC0gb25seV9NUlssYygxOjEyLDE0OjQyKV0KYGBgCgoKYGBge3J9CmFsbF9NUiA8LSByYmluZChvbmx5X01SLCBub19MUl9NUikKaGVhZChhbGxfTVIpCmRpbShhbGxfTVIpCmxlbmd0aCh1bmlxdWUoYWxsX01SJHJvb3RfbmFtZSkpCmxlbmd0aCh1bmlxdWUoYWxsX01SJGltYWdlKSkKCmxlbmd0aCh1bmlxdWUoYWxsX01SJGltYWdlKSkvbGVuZ3RoKHVuaXF1ZShhbGxfTVIkcm9vdF9uYW1lKSkKYGBgCkxldCdzIGFkZCBzb21lIG1vcmUgaW50ZXJlc3RpbmcgY29sdW1uczoKCmBgYHtyfQphbGxfTVIkTFJMIDwtIChhbGxfTVIkTFJMXzEwXzEwMCArIGFsbF9NUiRMUkxfMjBfMTAwICsgYWxsX01SJExSTF8zMF8xMDAgKyBhbGxfTVIkTFJMXzQwXzEwMCArIGFsbF9NUiRMUkxfNTBfMTAwICsgYWxsX01SJExSTF82MF8xMDAgKyBhbGxfTVIkTFJMXzcwXzEwMCArIGFsbF9NUiRMUkxfODBfMTAwICsgYWxsX01SJExSTF85MF8xMDAgKyBhbGxfTVIkTFJMXzEwMF8xMDApCmFsbF9NUiRMUm5vIDwtIChhbGxfTVIkTFJfbm9fMTBfMTAwICsgYWxsX01SJExSX25vXzIwXzEwMCArIGFsbF9NUiRMUl9ub18zMF8xMDAgKyBhbGxfTVIkTFJfbm9fNDBfMTAwICsgYWxsX01SJExSX25vXzUwXzEwMCArIGFsbF9NUiRMUl9ub182MF8xMDAgKyBhbGxfTVIkTFJfbm9fNzBfMTAwICsgYWxsX01SJExSX25vXzgwXzEwMCArIGFsbF9NUiRMUl9ub185MF8xMDAgKyBhbGxfTVIkTFJfbm9fMTAwXzEwMCkKYWxsX01SJGFMUkwgPC0gYWxsX01SJExSTCAvIGFsbF9NUiRMUm5vCmFsbF9NUiRUUlMgPC0gYWxsX01SJE1STCArIGFsbF9NUiRMUkwKaGVhZChhbGxfTVIpCmBgYAoKIyBkYXRhIHZpc3VhbGl6YXRpb24KCk9LIC0gbm93IHdlIGhhdmUgYWxsIHRoZSB0cmFpdHMgY2FsY3VsYXRlZCAtIGJ1dCB3ZSBhcmUgc3RpbGwgbWlzc2luZyB0aGUgREFZIGluZm9ybWF0aW9uIC0gYXMgaW4gREFZIGFmdGVyIHN0cmVzcy4gU28gbGV0J3MgY2FsY3VsYXRlIGl0IHBlciBleHBlcmltZW50OgoKYGBge3J9CmhlYWQoYWxsX01SKQp1bmlxdWUoYWxsX01SWyxjKCJleHBlcmltZW50IiwgImRhdGUiKV0pCmBgYAoKYmFzZWQgb24gdGhlIGFib3ZlIC0gd2UgaGF2ZSB0aGUgZm9sbG93aW5nCgpkYXkgICAgICBCaWcwMSAgICAgIEJpZzAyICAgICBCaWcwMyAgICAgIEJpZzA0CmRheSAwIC0gMjAxOTA5MDkgICAyMDE5MDkyMyAgMjAxOTA5MzAgIDIwMTkxMDA4CmRheSAxIC0gMjAxOTA5MTAgICAyMDE5MDkyNCAgMjAxOTEwMDEgIDIwMTkxMDA5CmRheSAyIC0gMjAxOTA5MTEgICAyMDE5MDkyNSAgMjAxOTEwMDIgIDIwMTkxMDEwCmRheSAzIC0gMjAxOTA5MTIgICAyMDE5MDkyNiAgMjAxOTEwMDMgIDIwMTkxMDExCmRheSA0IC0gMjAxOTA5MTMgICAyMDE5MDkyNyAgMjAxOTEwMDQgIDIwMTkxMDEyCgpTbyBub3cgd2UgaGF2ZSB0byBkbyBjb25kaXRpb25hbCBmb3JtYXRpbmcgZm9yIERBUyAoRGF5cyBBZnRlciBTdHJlc3MpOgoKYGBge3J9CmFsbF9NUiREQVMgPC0gYWxsX01SJGRhdGUKYWxsX01SJERBUyA8LSBnc3ViKCIyMDE5MDkwOSIsICIwIiwgYWxsX01SJERBUykKYWxsX01SJERBUyA8LSBnc3ViKCIyMDE5MDkyMyIsICIwIiwgYWxsX01SJERBUykKYWxsX01SJERBUyA8LSBnc3ViKCIyMDE5MDkzMCIsICIwIiwgYWxsX01SJERBUykKYWxsX01SJERBUyA8LSBnc3ViKCIyMDE5MTAwOCIsICIwIiwgYWxsX01SJERBUykKCmFsbF9NUiREQVMgPC0gZ3N1YigiMjAxOTA5MTAiLCAiMSIsIGFsbF9NUiREQVMpCmFsbF9NUiREQVMgPC0gZ3N1YigiMjAxOTA5MjQiLCAiMSIsIGFsbF9NUiREQVMpCmFsbF9NUiREQVMgPC0gZ3N1YigiMjAxOTEwMDEiLCAiMSIsIGFsbF9NUiREQVMpCmFsbF9NUiREQVMgPC0gZ3N1YigiMjAxOTEwMDkiLCAiMSIsIGFsbF9NUiREQVMpCgphbGxfTVIkREFTIDwtIGdzdWIoIjIwMTkwOTExIiwgIjIiLCBhbGxfTVIkREFTKQphbGxfTVIkREFTIDwtIGdzdWIoIjIwMTkwOTI1IiwgIjIiLCBhbGxfTVIkREFTKQphbGxfTVIkREFTIDwtIGdzdWIoIjIwMTkxMDAyIiwgIjIiLCBhbGxfTVIkREFTKQphbGxfTVIkREFTIDwtIGdzdWIoIjIwMTkxMDEwIiwgIjIiLCBhbGxfTVIkREFTKQoKYWxsX01SJERBUyA8LSBnc3ViKCIyMDE5MDkxMiIsICIzIiwgYWxsX01SJERBUykKYWxsX01SJERBUyA8LSBnc3ViKCIyMDE5MDkyNiIsICIzIiwgYWxsX01SJERBUykKYWxsX01SJERBUyA8LSBnc3ViKCIyMDE5MTAwMyIsICIzIiwgYWxsX01SJERBUykKYWxsX01SJERBUyA8LSBnc3ViKCIyMDE5MTAxMSIsICIzIiwgYWxsX01SJERBUykKCmFsbF9NUiREQVMgPC0gZ3N1YigiMjAxOTA5MTMiLCAiNCIsIGFsbF9NUiREQVMpCmFsbF9NUiREQVMgPC0gZ3N1YigiMjAxOTA5MjciLCAiNCIsIGFsbF9NUiREQVMpCmFsbF9NUiREQVMgPC0gZ3N1YigiMjAxOTEwMDQiLCAiNCIsIGFsbF9NUiREQVMpCmFsbF9NUiREQVMgPC0gZ3N1YigiMjAxOTEwMTIiLCAiNCIsIGFsbF9NUiREQVMpCgp1bmlxdWUoYWxsX01SWyxjKCJleHBlcmltZW50IiwgIkRBUyIpXSkKYGBgCgoKYmVmb3JlIHdlIGdvIGFueSBmdXJ0aGVyIC0gbGV0J3MgY2xlYW4gdXAgdGhpcyBkYXRhIGFuZCBhZGQgd2hhdGV2ZXIgZWxzZSBtaXNzaW5nIHRyYWl0czoKCmBgYHtyfQpjb2xuYW1lcyhhbGxfTVIpCmRpbShhbGxfTVIpCmFsbF9NUjIgPC0gYWxsX01SWyxjKDE6NCwgNDYsIDY6OSwgMTM6NDUpXQpoZWFkKGFsbF9NUjIpCmFsbF9NUjIkTVJMLnAuVFJTIDwtIGFsbF9NUjIkTVJMIC8gYWxsX01SMiRUUlMKYWxsX01SMiRhTFJMLnAuVFJTIDwtIGFsbF9NUjIkYUxSTCAvIGFsbF9NUjIkVFJTCmFsbF9NUjIkTFJMXzEwX3BlcmMgPC0gYWxsX01SMiRMUkxfMTBfMTAwIC8gYWxsX01SMiRMUkwKYWxsX01SMiRMUkxfMjBfcGVyYyA8LSBhbGxfTVIyJExSTF8yMF8xMDAgLyBhbGxfTVIyJExSTAphbGxfTVIyJExSTF8zMF9wZXJjIDwtIGFsbF9NUjIkTFJMXzMwXzEwMCAvIGFsbF9NUjIkTFJMCmFsbF9NUjIkTFJMXzQwX3BlcmMgPC0gYWxsX01SMiRMUkxfNDBfMTAwIC8gYWxsX01SMiRMUkwKYWxsX01SMiRMUkxfNTBfcGVyYyA8LSBhbGxfTVIyJExSTF81MF8xMDAgLyBhbGxfTVIyJExSTAphbGxfTVIyJExSTF82MF9wZXJjIDwtIGFsbF9NUjIkTFJMXzYwXzEwMCAvIGFsbF9NUjIkTFJMCmFsbF9NUjIkTFJMXzcwX3BlcmMgPC0gYWxsX01SMiRMUkxfNzBfMTAwIC8gYWxsX01SMiRMUkwKYWxsX01SMiRMUkxfODBfcGVyYyA8LSBhbGxfTVIyJExSTF84MF8xMDAgLyBhbGxfTVIyJExSTAphbGxfTVIyJExSTF85MF9wZXJjIDwtIGFsbF9NUjIkTFJMXzkwXzEwMCAvIGFsbF9NUjIkTFJMCmFsbF9NUjIkTFJMXzEwMF9wZXJjIDwtIGFsbF9NUjIkTFJMXzEwMF8xMDAgLyBhbGxfTVIyJExSTAoKYWxsX01SMiRMUm5vXzEwX3BlcmMgPC0gYWxsX01SMiRMUl9ub18xMF8xMDAgLyBhbGxfTVIyJExSbm8KYWxsX01SMiRMUm5vXzIwX3BlcmMgPC0gYWxsX01SMiRMUl9ub18yMF8xMDAgLyBhbGxfTVIyJExSbm8KYWxsX01SMiRMUm5vXzMwX3BlcmMgPC0gYWxsX01SMiRMUl9ub18zMF8xMDAgLyBhbGxfTVIyJExSbm8KYWxsX01SMiRMUm5vXzQwX3BlcmMgPC0gYWxsX01SMiRMUl9ub180MF8xMDAgLyBhbGxfTVIyJExSbm8KYWxsX01SMiRMUm5vXzUwX3BlcmMgPC0gYWxsX01SMiRMUl9ub181MF8xMDAgLyBhbGxfTVIyJExSbm8KYWxsX01SMiRMUm5vXzYwX3BlcmMgPC0gYWxsX01SMiRMUl9ub182MF8xMDAgLyBhbGxfTVIyJExSbm8KYWxsX01SMiRMUm5vXzcwX3BlcmMgPC0gYWxsX01SMiRMUl9ub183MF8xMDAgLyBhbGxfTVIyJExSbm8KYWxsX01SMiRMUm5vXzgwX3BlcmMgPC0gYWxsX01SMiRMUl9ub184MF8xMDAgLyBhbGxfTVIyJExSbm8KYWxsX01SMiRMUm5vXzkwX3BlcmMgPC0gYWxsX01SMiRMUl9ub185MF8xMDAgLyBhbGxfTVIyJExSbm8KYWxsX01SMiRMUm5vXzEwMF9wZXJjIDwtIGFsbF9NUjIkTFJfbm9fMTAwXzEwMCAvIGFsbF9NUjIkTFJubwoKaGVhZChhbGxfTVIyKQpgYGAKCkp1c3QgYmVmb3JlIHdlIHN0YXJ0IHBsb3R0aW5nIHRoZSBkYXRhIC0gbGV0J3MgYWxzbyBjaGVjayB0aGUgZ2Vub3R5cGUgaW5mb3JtYXRpb24gd2hldGhlciB0aGlzIGFsbCBtYWtlcyBzZW5zZSBhbmQgaWYgd2UgYXJlIG5vdCBtaXNzaW5nIGFueSBpbmZvOgoKYGBge3J9CnVuaXF1ZShhbGxfTVIyJGdlbm90eXBlKQp1bmlxdWUoYWxsX01SJHJvb3RfbmFtZSkKCmFsbF9NUjIkZ2Vub3R5cGUgPC0gZ3N1YigiMjgwMCIsICIyODAiLCBhbGxfTVIyJGdlbm90eXBlKQphbGxfTVIyJHJvb3RfbmFtZSA8LSBnc3ViKCIgMDg5XzFfIiwgIiAwODlfMV9DIiwgYWxsX01SMiRyb290X25hbWUpCmFsbF9NUjIkcm9vdF9uYW1lIDwtIGdzdWIoIiAwODlfMV9DX0MiLCAiIDA4OV8xX0MiLCBhbGxfTVIyJHJvb3RfbmFtZSkKYWxsX01SMiRyb290X25hbWUgPC0gZ3N1YigiIDA4OV8xX0NfUyIsICIgMDg5XzFfUyIsIGFsbF9NUjIkcm9vdF9uYW1lKQoKYWxsX01SMiRyb290X25hbWUgPC0gZ3N1YigiMzAxXzMiLCAiMzAxXzNfQyIsIGFsbF9NUjIkcm9vdF9uYW1lKQphbGxfTVIyJHJvb3RfbmFtZSA8LSBnc3ViKCIzMDFfM19DQyIsICIzMDFfM19DIiwgYWxsX01SMiRyb290X25hbWUpCmFsbF9NUjIkcm9vdF9uYW1lIDwtIGdzdWIoIjMwMV8zX0NTIiwgIjMwMV8zX1MiLCBhbGxfTVIyJHJvb3RfbmFtZSkKCnVuaXF1ZShhbGxfTVIyJGNvbmQpCmFsbF9NUjIkY29uZCA8LSBnc3ViKCJzIiwgIlMiLCBhbGxfTVIyJGNvbmQpCnVuaXF1ZShhbGxfTVIyJGNvbmQpCgpub3JtYWxfY29uZCA8LSBjKCJDIiwgIlMiKQp0aGF0c19pdCA8LSBzdWJzZXQoYWxsX01SMiwgKGFsbF9NUjIkY29uZCAlaW4lIG5vcm1hbF9jb25kKSkKd2hhdHNfdGhhdCA8LSBzdWJzZXQoYWxsX01SMiwgIShhbGxfTVIyJGNvbmQgJWluJSBub3JtYWxfY29uZCkpCndoYXRzX3RoYXQKd2hhdHNfdGhhdCRjb25kIDwtICJDIgoKYWxsX01SMyA8LSByYmluZCh0aGF0c19pdCwgd2hhdHNfdGhhdCkKdW5pcXVlKGFsbF9NUjMkY29uZCkKYGBgCgoKIyMgSGlzdG9ncmFtcwoKIyMjIExpYnJhcnkgbG9hZGluZwpPSyAtIG5vdyB3ZSBjYW4gc3RhcnQgcGxvdHRpbmcgLSBmaW5hbGx5ISBsb2FkaW5nIHRoZSBsaWJyYXJpZXMKCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2dwdWJyKQpsaWJyYXJ5KGRvQnkpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkoY29ycnBsb3QpCmxpYnJhcnkoZ2diZWVzd2FybSkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkoZ2dyaWRnZXMpCmxpYnJhcnkoZ2FwbWluZGVyKQpsaWJyYXJ5KCJncGxvdHMiKQpsaWJyYXJ5KCJjb2xvclJhbXBzIikKYGBgCgpMZXQncyBzdGFydCBmcm9tIGEgc2ltcGxlIGhpc3RvZ3JhbSAtIHNvIHdlIGNhbiBzZWUgdGhlIHRyZWF0bWVudCBkZXBlbmRlbnQgY2hhbmdlIGluIFRSUwoKYGBge3J9ClRSU19oaXN0byA8LSBnZ2hpc3RvZ3JhbShhbGxfTVIzLCB4ID0gIlRSUyIsCiAgICAgICAgICAgIGFkZCA9ICJtZWFuIiwgcnVnID0gVFJVRSwKICAgICAgICAgICAgY29sb3IgPSAiY29uZCIsIGZpbGwgPSAiY29uZCIsIGZhY2V0LmJ5ID0gIkRBUyIsIAogICAgICAgICAgICBwYWxldHRlID0gYygiIzAwQUZCQiIsICIjRTdCODAwIikpICsgeGxhYigiVG90YWwgcm9vdCBsZW5ndGggKGNtKSIpClRSU19oaXN0bwpgYGAKCk9LIC0gbG9va3MgYXMgd2UgZXhwZWN0IGl0IHRvLiBMZXQncyBoYXZlIGEgbG9vayBhdCBvdGhlciB0aGluZ3MgLSBsaWtlIExSIG51bWJlcjoKCmBgYHtyfQpMUm5vX2hpc3RvIDwtIGdnaGlzdG9ncmFtKGFsbF9NUjMsIHggPSAiTFJubyIsCiAgICAgICAgICAgIGFkZCA9ICJtZWFuIiwgcnVnID0gVFJVRSwKICAgICAgICAgICAgY29sb3IgPSAiY29uZCIsIGZpbGwgPSAiY29uZCIsIGZhY2V0LmJ5ID0gIkRBUyIsCiAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwgIiNFN0I4MDAiKSkgKyB4bGFiKCJudW1iZXIgb2YgTFIgLyBNYWluIFJvb3QiKQpMUm5vX2hpc3RvCmBgYAoKYGBge3J9CkxSTF9oaXN0byA8LSBnZ2hpc3RvZ3JhbShhbGxfTVIzLCB4ID0gIkxSTCIsCiAgICAgICAgICAgIGFkZCA9ICJtZWFuIiwgcnVnID0gVFJVRSwKICAgICAgICAgICAgY29sb3IgPSAiY29uZCIsIGZpbGwgPSAiY29uZCIsIGZhY2V0LmJ5ID0gIkRBUyIsCiAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwgIiNFN0I4MDAiKSkgKyB4bGFiKCJMYXRlcmFsIFJvb3QgTGVuZ3RoIChjbSkiKQpMUkxfaGlzdG8KYGBgCgpgYGB7cn0KTVJMX2hpc3RvIDwtIGdnaGlzdG9ncmFtKGFsbF9NUjMsIHggPSAiTVJMIiwKICAgICAgICAgICAgYWRkID0gIm1lYW4iLCBydWcgPSBUUlVFLAogICAgICAgICAgICBjb2xvciA9ICJjb25kIiwgZmlsbCA9ICJjb25kIiwgZmFjZXQuYnkgPSAiREFTIiwKICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIpKSArIHhsYWIoIk1haW4gcm9vdCBsZW5ndGggKGNtKSIpCk1STF9oaXN0bwpgYGAKCmBgYHtyfQpDb0dfaGlzdG8gPC0gZ2doaXN0b2dyYW0oYWxsX01SMywgeCA9ICJDb0ciLAogICAgICAgICAgICBhZGQgPSAibWVhbiIsIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgIGNvbG9yID0gImNvbmQiLCBmaWxsID0gImNvbmQiLCBmYWNldC5ieSA9ICJEQVMiLAogICAgICAgICAgICBwYWxldHRlID0gYygiIzAwQUZCQiIsICIjRTdCODAwIikpICsgeGxhYigiQ2VudGVyIG9mIEdyYXZpdHkgKGNtIG9mIE1SKSIpCkNvR19oaXN0bwpgYGAKCmBgYHtyfQphbGxfTVIzJExSTC5kZWMgPC0gYXMubnVtZXJpYyhhbGxfTVIzJExSTC5kZWMpCkxSTC5kZWNfaGlzdG8gPC0gZ2doaXN0b2dyYW0oYWxsX01SMywgeCA9ICJMUkwuZGVjIiwKICAgICAgICAgICAgYWRkID0gIm1lYW4iLCBydWcgPSBUUlVFLAogICAgICAgICAgICBjb2xvciA9ICJjb25kIiwgZmlsbCA9ICJjb25kIiwgZmFjZXQuYnkgPSAiREFTIiwKICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIpKSArIHhsYWIoIkxhdGVyYWwgUm9vdCBMZW5ndGggZGVjcmVhc2Ugb3ZlciBNUiAoY20gLyBjbSBvZiBNUikiKQpMUkwuZGVjX2hpc3RvCmBgYAoKdGhlIGFib3ZlIGRvZXNudCByZWFsbHkgbWFrZSBzZW5zZSAtIGxldCdzIHJlcGxhY2UgYWxsIHRoZXNlIGV4dHJlbWUgdmFsdWVzICg8IC0yLCA+IDIpIHdpdGggIm4uYS4iKQoKYGBge3J9CnRlbXAgPC0gc3Vic2V0KGFsbF9NUjMsIGFsbF9NUjMkTFJMLmRlYyA8IDIpCnRlbXAgPC0gc3Vic2V0KHRlbXAsIHRlbXAkTFJMLmRlYyA+IC0yKQoKTFJMLmRlY19oaXN0byA8LSBnZ2hpc3RvZ3JhbSh0ZW1wLCB4ID0gIkxSTC5kZWMiLAogICAgICAgICAgICBhZGQgPSAibWVhbiIsIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgIGNvbG9yID0gImNvbmQiLCBmaWxsID0gImNvbmQiLCBmYWNldC5ieSA9ICJEQVMiLAogICAgICAgICAgICBwYWxldHRlID0gYygiIzAwQUZCQiIsICIjRTdCODAwIikpICsgeGxhYigiTGF0ZXJhbCBSb290IExlbmd0aCBkZWNyZWFzZSBvdmVyIE1SIChjbSAvIGNtIG9mIE1SKSIpCkxSTC5kZWNfaGlzdG8KCmBgYAoKCgpgYGB7cn0KYWxsX01SMyRMUkwuZGVjLlIyIDwtIGFzLm51bWVyaWMoYWxsX01SMyRMUkwuZGVjLlIyKQpMUkwuZGVjLlIyX2hpc3RvIDwtIGdnaGlzdG9ncmFtKGFsbF9NUjMsIHggPSAiTFJMLmRlYy5SMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkID0gIm1lYW4iLCBydWcgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImNvbmQiLCBmaWxsID0gImNvbmQiLCBmYWNldC5ieSA9ICJEQVMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwgIiNFN0I4MDAiKSkgKyB4bGFiKCJSMiBvZiBMYXRlcmFsIFJvb3QgTGVuZ3RoIGRlY3JlYXNlIG92ZXIgTVIiKQpMUkwuZGVjLlIyX2hpc3RvCmBgYAoKIyMgdmlzdWFsaXphdGlvbiBvZiBjaGFuZ2VzIGluIFJTQSBhY3Jvc3MgdGltZToKCkxldCdzIHRyeSB0byB2aXN1YWxpemUgY2hhbmdlcyBhY3Jvc3MgdGhlIGFjY2Vzc2lvbnMgdGhyb3VnaG91dCB0aGUgdGltZSB1c2luZyB0aGUgbGluZSBncmFwaCAtIHNpbWlsYXIgdG8gb25lcyBpbiBBd2xpYSBldCBhbC4sIDIwMjAKCkZpcnN0IC0gd2hhdCB3ZSBuZWVkIHRvIGRvIGlzIHRvIGNhbGN1bGF0ZSB0aGUgYXZlcmFnZSBwZXIgbGluZSBhbmQgcGVyIGNvbmRpdGlvbjoKCmBgYHtyfQpjb2xuYW1lcyhhbGxfTVIzKQpsaWJyYXJ5KGRvQnkpCgpNUl9zdW0gPC0gc3VtbWFyeUJ5KGRhdGEgPSBhbGxfTVIzLCBNUkwgKyBMUkwgKyBMUm5vICsgYUxSTCArIFRSUyArIE1STC5wLlRSUyArIGFMUkwucC5UUlMgKyBDb0cgKyBMUkwuZGVjIH4gZ2Vub3R5cGUgKyBjb25kICsgREFTKQpoZWFkKE1SX3N1bSkKTVJfc3VtJGdlbm9fY29uZCA8LSBwYXN0ZShNUl9zdW0kZ2Vub3R5cGUsICJfIiwgTVJfc3VtJGNvbmQsIHNlcD0iIikKYGBgCgpgYGB7cn0KVFJTX2xncmFwaCA8LSBnZ3Bsb3QoZGF0YT1NUl9zdW0sIGFlcyh4PSBEQVMsIHk9VFJTLm1lYW4sIGdyb3VwID0gZ2Vub19jb25kLCBjb2xvciA9IGNvbmQpKSAKVFJTX2xncmFwaCA8LSBUUlNfbGdyYXBoICtnZW9tX2xpbmUoYWxwaGEgPSAwLjEpIApUUlNfbGdyYXBoIDwtIFRSU19sZ3JhcGggKyBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NlLCBnZW9tPSJyaWJib24iLCBsaW5ldHlwZT0wLCBhZXMoZ3JvdXA9Y29uZCksIGFscGhhPTAuMykrIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpUUlNfbGdyYXBoIDwtIFRSU19sZ3JhcGggKyBzdGF0X2NvbXBhcmVfbWVhbnMoYWVzKGdyb3VwID0gY29uZCksIGxhYmVsID0gInAuc2lnbmlmIiwgbWV0aG9kID0gInQudGVzdCIsIGhpZGUubnMgPSBUKQpUUlNfbGdyYXBoIDwtIFRSU19sZ3JhcGggKyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoInN0ZWVsYmx1ZSIsICJmaXJlYnJpY2szIikpICsgZ2d0aXRsZSgiQXZlcmFnZSBwZXIgYWNjZXNzaW9uIikKVFJTX2xncmFwaCA8LSBUUlNfbGdyYXBoICsgeWxhYigiVG90YWwgUm9vdCBTaXplIChjbSkiKSArIHhsYWIoIkRheXMgQWZ0ZXIgU3RyZXNzIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249J25vbmUnKQpUUlNfbGdyYXBoCmBgYAoKYGBge3J9Ck1STF9sZ3JhcGggPC0gZ2dwbG90KGRhdGE9TVJfc3VtLCBhZXMoeD0gREFTLCB5PU1STC5tZWFuLCBncm91cCA9IGdlbm9fY29uZCwgY29sb3IgPSBjb25kKSkgCk1STF9sZ3JhcGggPC0gTVJMX2xncmFwaCArZ2VvbV9saW5lKGFscGhhID0gMC4xKSAKTVJMX2xncmFwaCA8LSBNUkxfbGdyYXBoICsgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gbWVhbl9zZSwgZ2VvbT0icmliYm9uIiwgbGluZXR5cGU9MCwgYWVzKGdyb3VwPWNvbmQpLCBhbHBoYT0wLjMpICsgc3RhdF9zdW1tYXJ5KGZ1bi55PW1lYW4sIGFlcyhncm91cD0gY29uZCksICBzaXplPTAuNywgZ2VvbT0ibGluZSIsIGxpbmV0eXBlID0gImRhc2hlZCIpCk1STF9sZ3JhcGggPC0gTVJMX2xncmFwaCArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCk1STF9sZ3JhcGggPC0gTVJMX2xncmFwaCArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygic3RlZWxibHVlIiwgImZpcmVicmljazMiKSkgKyBnZ3RpdGxlKCJBdmVyYWdlIHBlciBhY2Nlc3Npb24iKQpNUkxfbGdyYXBoIDwtIE1STF9sZ3JhcGggKyB5bGFiKCJNYWluIFJvb3QgTGVuZ3RoIChjbSkiKSArIHhsYWIoIkRheXMgQWZ0ZXIgU3RyZXNzIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249J25vbmUnKQpNUkxfbGdyYXBoCmBgYAoKCmBgYHtyfQpMUkxfbGdyYXBoIDwtIGdncGxvdChkYXRhPU1SX3N1bSwgYWVzKHg9IERBUywgeT1MUkwubWVhbiwgZ3JvdXAgPSBnZW5vX2NvbmQsIGNvbG9yID0gY29uZCkpIApMUkxfbGdyYXBoIDwtIExSTF9sZ3JhcGggK2dlb21fbGluZShhbHBoYSA9IDAuMSkgCkxSTF9sZ3JhcGggPC0gTFJMX2xncmFwaCArIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IG1lYW5fc2UsIGdlb209InJpYmJvbiIsIGxpbmV0eXBlPTAsIGFlcyhncm91cD1jb25kKSwgYWxwaGE9MC4zKSsgc3RhdF9zdW1tYXJ5KGZ1bi55PW1lYW4sIGFlcyhncm91cD0gY29uZCksICBzaXplPTAuNywgZ2VvbT0ibGluZSIsIGxpbmV0eXBlID0gImRhc2hlZCIpCkxSTF9sZ3JhcGggPC0gTFJMX2xncmFwaCArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCkxSTF9sZ3JhcGggPC0gTFJMX2xncmFwaCArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygic3RlZWxibHVlIiwgImZpcmVicmljazMiKSkgKyBnZ3RpdGxlKCJBdmVyYWdlIHBlciBhY2Nlc3Npb24iKQpMUkxfbGdyYXBoIDwtIExSTF9sZ3JhcGggKyB5bGFiKCJMYXRlcmFsIFJvb3QgTGVuZ3RoIChjbSkiKSArIHhsYWIoIkRheXMgQWZ0ZXIgU3RyZXNzIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249J25vbmUnKQpMUkxfbGdyYXBoCmBgYAoKCmBgYHtyfQpMUm5vX2xncmFwaCA8LSBnZ3Bsb3QoZGF0YT1NUl9zdW0sIGFlcyh4PSBEQVMsIHk9TFJuby5tZWFuLCBncm91cCA9IGdlbm9fY29uZCwgY29sb3IgPSBjb25kKSkgCkxSbm9fbGdyYXBoIDwtIExSbm9fbGdyYXBoICtnZW9tX2xpbmUoYWxwaGEgPSAwLjEpIApMUm5vX2xncmFwaCA8LSBMUm5vX2xncmFwaCArIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IG1lYW5fc2UsIGdlb209InJpYmJvbiIsIGxpbmV0eXBlPTAsIGFlcyhncm91cD1jb25kKSwgYWxwaGE9MC4zKSArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpMUm5vX2xncmFwaCA8LSBMUm5vX2xncmFwaCArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCkxSbm9fbGdyYXBoIDwtIExSbm9fbGdyYXBoICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJzdGVlbGJsdWUiLCAiZmlyZWJyaWNrMyIpKSArIGdndGl0bGUoIkF2ZXJhZ2UgcGVyIGFjY2Vzc2lvbiIpCkxSbm9fbGdyYXBoIDwtIExSbm9fbGdyYXBoICsgeWxhYigiTGF0ZXJhbCBSb290IE51bWJlciAocGVyIE1SKSIpICsgeGxhYigiRGF5cyBBZnRlciBTdHJlc3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScpCkxSbm9fbGdyYXBoCmBgYAoKYGBge3J9CkNvR19sZ3JhcGggPC0gZ2dwbG90KGRhdGE9TVJfc3VtLCBhZXMoeD0gREFTLCB5PUNvRy5tZWFuLCBncm91cCA9IGdlbm9fY29uZCwgY29sb3IgPSBjb25kKSkgCkNvR19sZ3JhcGggPC0gQ29HX2xncmFwaCArZ2VvbV9saW5lKGFscGhhID0gMC4xKSAKQ29HX2xncmFwaCA8LSBDb0dfbGdyYXBoICsgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gbWVhbl9zZSwgZ2VvbT0icmliYm9uIiwgbGluZXR5cGU9MCwgYWVzKGdyb3VwPWNvbmQpLCBhbHBoYT0wLjMpICsgc3RhdF9zdW1tYXJ5KGZ1bi55PW1lYW4sIGFlcyhncm91cD0gY29uZCksICBzaXplPTAuNywgZ2VvbT0ibGluZSIsIGxpbmV0eXBlID0gImRhc2hlZCIpCkNvR19sZ3JhcGggPC0gQ29HX2xncmFwaCArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCkNvR19sZ3JhcGggPC0gQ29HX2xncmFwaCArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygic3RlZWxibHVlIiwgImZpcmVicmljazMiKSkgKyBnZ3RpdGxlKCJBdmVyYWdlIHBlciBhY2Nlc3Npb24iKQpDb0dfbGdyYXBoIDwtIENvR19sZ3JhcGggKyB5bGFiKCJDZW50ZXIgb2YgR3Jhdml0eSAoY20gb2YgTVIpIikgKyB4bGFiKCJEYXlzIEFmdGVyIFN0cmVzcyIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSdub25lJykKQ29HX2xncmFwaApgYGAKCmBgYHtyfQpMUkwuZGVjX2xncmFwaCA8LSBnZ3Bsb3QoZGF0YT1NUl9zdW0sIGFlcyh4PSBEQVMsIHk9TFJMLmRlYy5tZWFuLCBncm91cCA9IGdlbm9fY29uZCwgY29sb3IgPSBjb25kKSkgCkxSTC5kZWNfbGdyYXBoIDwtIExSTC5kZWNfbGdyYXBoICtnZW9tX2xpbmUoYWxwaGEgPSAwLjEpIApMUkwuZGVjX2xncmFwaCA8LSBMUkwuZGVjX2xncmFwaCArIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IG1lYW5fc2UsIGdlb209InJpYmJvbiIsIGxpbmV0eXBlPTAsIGFlcyhncm91cD1jb25kKSwgYWxwaGE9MC4zKSArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpMUkwuZGVjX2xncmFwaCA8LSBMUkwuZGVjX2xncmFwaCArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCkxSTC5kZWNfbGdyYXBoIDwtIExSTC5kZWNfbGdyYXBoICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJzdGVlbGJsdWUiLCAiZmlyZWJyaWNrMyIpKSArIGdndGl0bGUoIkF2ZXJhZ2UgcGVyIGFjY2Vzc2lvbiIpCkxSTC5kZWNfbGdyYXBoIDwtIExSTC5kZWNfbGdyYXBoICsgeWxhYigiZGVjcmVhc2Ugb2YgTFJMIG92ZXIgTVJMIChjbSAvIGNtIG9mIE1SKSIpICsgeGxhYigiRGF5cyBBZnRlciBTdHJlc3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScpCkxSTC5kZWNfbGdyYXBoCmBgYAoKYGBge3J9Ck1STC5wLlRSU19sZ3JhcGggPC0gZ2dwbG90KGRhdGE9TVJfc3VtLCBhZXMoeD0gREFTLCB5PU1STC5wLlRSUy5tZWFuLCBncm91cCA9IGdlbm9fY29uZCwgY29sb3IgPSBjb25kKSkgCk1STC5wLlRSU19sZ3JhcGggPC0gTVJMLnAuVFJTX2xncmFwaCArZ2VvbV9saW5lKGFscGhhID0gMC4xKSAKTVJMLnAuVFJTX2xncmFwaCA8LSBNUkwucC5UUlNfbGdyYXBoICsgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gbWVhbl9zZSwgZ2VvbT0icmliYm9uIiwgbGluZXR5cGU9MCwgYWVzKGdyb3VwPWNvbmQpLCBhbHBoYT0wLjMpICsgc3RhdF9zdW1tYXJ5KGZ1bi55PW1lYW4sIGFlcyhncm91cD0gY29uZCksICBzaXplPTAuNywgZ2VvbT0ibGluZSIsIGxpbmV0eXBlID0gImRhc2hlZCIpCk1STC5wLlRSU19sZ3JhcGggPC0gTVJMLnAuVFJTX2xncmFwaCArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCk1STC5wLlRSU19sZ3JhcGggPC0gTVJMLnAuVFJTX2xncmFwaCArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygic3RlZWxibHVlIiwgImZpcmVicmljazMiKSkgKyBnZ3RpdGxlKCJBdmVyYWdlIHBlciBhY2Nlc3Npb24iKQpNUkwucC5UUlNfbGdyYXBoIDwtIE1STC5wLlRSU19sZ3JhcGggKyB5bGFiKCJyYXRpbyAoTVJMIC8gVFJTKSIpICsgeGxhYigiRGF5cyBBZnRlciBTdHJlc3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScpCk1STC5wLlRSU19sZ3JhcGgKYGBgCgpgYGB7cn0KYUxSTC5wLlRSU19sZ3JhcGggPC0gZ2dwbG90KGRhdGE9TVJfc3VtLCBhZXMoeD0gREFTLCB5PWFMUkwucC5UUlMubWVhbiwgZ3JvdXAgPSBnZW5vX2NvbmQsIGNvbG9yID0gY29uZCkpIAphTFJMLnAuVFJTX2xncmFwaCA8LSBhTFJMLnAuVFJTX2xncmFwaCArZ2VvbV9saW5lKGFscGhhID0gMC4xKSAKYUxSTC5wLlRSU19sZ3JhcGggPC0gYUxSTC5wLlRSU19sZ3JhcGggKyBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NlLCBnZW9tPSJyaWJib24iLCBsaW5ldHlwZT0wLCBhZXMoZ3JvdXA9Y29uZCksIGFscGhhPTAuMykKYUxSTC5wLlRSU19sZ3JhcGggPC0gYUxSTC5wLlRSU19sZ3JhcGggKyBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgYWVzKGdyb3VwPSBjb25kKSwgIHNpemU9MC43LCBnZW9tPSJsaW5lIiwgbGluZXR5cGUgPSAiZGFzaGVkIikKYUxSTC5wLlRSU19sZ3JhcGggPC0gYUxSTC5wLlRSU19sZ3JhcGggKyBzdGF0X2NvbXBhcmVfbWVhbnMoYWVzKGdyb3VwID0gY29uZCksIGxhYmVsID0gInAuc2lnbmlmIiwgbWV0aG9kID0gInQudGVzdCIsIGhpZGUubnMgPSBUKQphTFJMLnAuVFJTX2xncmFwaCA8LSBhTFJMLnAuVFJTX2xncmFwaCArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygic3RlZWxibHVlIiwgImZpcmVicmljazMiKSkgKyBnZ3RpdGxlKCJBdmVyYWdlIHBlciBhY2Nlc3Npb24iKQphTFJMLnAuVFJTX2xncmFwaCA8LSBhTFJMLnAuVFJTX2xncmFwaCArIHlsYWIoInJhdGlvIChhTFJMIC8gVFJTKSIpICsgeGxhYigiRGF5cyBBZnRlciBTdHJlc3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScpCmFMUkwucC5UUlNfbGdyYXBoCmBgYAoKTGV0cyBjb21iaW5lIHRoZXNlIGludG8gb25lIGZpZ3VyZToKCmBgYHtyfQpwZGYoIkZpZy5UUlNfTVJMX0xSTF9MUm5vX0NvR19NUkxwVFJTX0JpZzAxX3RvX0JpZzA0LnBkZiIsIGhlaWdodCA9IDIwLCB3aWR0aCA9IDE1KQpwbG90X2dyaWQoVFJTX2xncmFwaCwgTVJMX2xncmFwaCwKICAgICAgICAgIExSTF9sZ3JhcGgsIExSbm9fbGdyYXBoLAogICAgICAgICAgQ29HX2xncmFwaCwgTVJMLnAuVFJTX2xncmFwaCwgbmNvbD0yLCBsYWJlbHMgPSAiQVVUTyIpCmRldi5vZmYoKQpgYGAKCgpPSyAtIGxldCdzIGtlZXAgZ29pbmcgd2l0aCBleHBsb3Jpbmcgb3RoZXIgY29vbCB0cmFpdHMuLi4KCiMjIFZpenVhbGl6YXRpb24gb2YgTFJML0xSbm8gZGlzdHJpYnV0aW9uIGFjcm9zcyB0aGUgcm9vdDoKCkluIG9yZGVyIHRvIGV4YW1pbmUgaG93IHRoZSBMUiBpcyBkaXN0cmlidXRlZCBhY3Jvc3MgTVIgLSBsZXRzIGV4dHJhY3QgYWxsIHRoZSBMUiBkaXN0cmlidXRpb24gdHJhaXRzCgpgYGB7cn0KY29sbmFtZXMoYWxsX01SMykKZGltKGFsbF9NUjMpCkxSX2Rpc3RyaWJ1dGlvbiA8LSBhbGxfTVIzWyxjKDE6OCwgMTY6NjQpXQpjb2xuYW1lcyhMUl9kaXN0cmlidXRpb24pCmBgYAoKQ29vbCAtIHRoZW4gbGV0J3MgZXh0cmFjdCBvbmx5IHRoZSBsYXN0IGRheSwgcmVzaGFwZSB0aGUgZGF0YSBhbmQgcGxvdCB0aGUgYWJzb2x1dGUgTFJubyBhbmQgTFJMIGFjcm9zcyB0aGUgTVIgcG9ydGlvbnM6CgojIyMgNCBkYXlzIGFmdGVyIHN0cmVzcwoKYGBge3J9CmRheTQgPC0gc3Vic2V0KExSX2Rpc3RyaWJ1dGlvbiwgTFJfZGlzdHJpYnV0aW9uJERBUyA9PSA0KQpoZWFkKGRheTQpCmNvbG5hbWVzKGRheTQpCkxSbm8gPC0gZGF5NFssYygxOjE4KV0KaGVhZChMUm5vKQpMUkwgPC0gZGF5NFssYygxOjgsMTk6MjgpXQpsaWJyYXJ5KHJlc2hhcGUyKQptTFJubyA8LSBtZWx0KExSbm8sIHZhbHVlLm5hbWUgPSAiTFJubyIpCm1MUkwgPC0gbWVsdChMUkwsIHZhbHVlLm5hbWUgPSAiTFJMIikKaGVhZChtTFJubykKaGVhZChtTFJMKQpgYGAKCmNvb2wgLSBub3cgbGV0J3MgYWRqdXN0IHRoZSBwb3J0aW9uIG9mIHRoZSBNUiB0aGF0IGlzIGJlaW5nIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSBMUiBkaXN0cmlidXRpb24gaW4gInZhcmlhYmxlIiBjb2x1bW5zOgoKYGBge3J9Cm1MUm5vJHZhcmlhYmxlIDwtIGdzdWIoIkxSX25vXyIsICIiLCBtTFJubyR2YXJpYWJsZSkKbUxSbm8kdmFyaWFibGUgPC0gZ3N1YigiXzEwMCIsICIiLCBtTFJubyR2YXJpYWJsZSkKCm1MUkwkdmFyaWFibGUgPC0gZ3N1YigiTFJMXyIsICIiLCBtTFJMJHZhcmlhYmxlKQptTFJMJHZhcmlhYmxlIDwtIGdzdWIoIl8xMDAiLCAiIiwgbUxSTCR2YXJpYWJsZSkKCm1MUkwkdmFyaWFibGUgPC0gYXMubnVtZXJpYyhtTFJMJHZhcmlhYmxlKQptTFJubyR2YXJpYWJsZSA8LSBhcy5udW1lcmljKG1MUm5vJHZhcmlhYmxlKQpjb2xuYW1lcyhtTFJMKVs5XSA8LSAicGVyYy5vZi5NUkwiCmNvbG5hbWVzKG1MUm5vKVs5XSA8LSAicGVyYy5vZi5NUkwiCmhlYWQobUxSTCkKaGVhZChtTFJubykKCmBgYAoKYGBge3J9CkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDQgPC0gZ2dwbG90KGRhdGE9bUxSTCwgYWVzKHg9IHBlcmMub2YuTVJMLCB5PUxSTCwgZ3JvdXAgPSByb290X25hbWUsIGNvbG9yID0gY29uZCkpIApMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0IDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDQgKyBnZW9tX2xpbmUoYWxwaGEgPSAwLjEpICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJkb2RnZXJibHVlMyIsICJ0b21hdG8xIikpIApMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0IDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDQgKyBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgYWVzKGdyb3VwPSBjb25kKSwgIHNpemU9MC43LCBnZW9tPSJsaW5lIiwgbGluZXR5cGUgPSAiZGFzaGVkIikKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCA8LSBMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0ICsgc3RhdF9zdW1tYXJ5KGdlb20gPSAicmliYm9uIiwgbGluZXR5cGU9MCwgZnVuLmRhdGEgPSBtZWFuX2NsX25vcm1hbCwgYWVzKGdyb3VwPSBjb25kKSwgYWxwaGEgPSAwLjIpICArIGdndGl0bGUoIjQgRGF5cyBBZnRlciBTdHJlc3MiKQpMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0IDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDQgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsgbGFicyhjb2xvciA9ICJUcmVhdG1lbnQiKQpMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0IDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDQgKyB5bGFiKCJMYXRlcmFsIFJvb3QgTGVuZ3RoIChjbSkiKSArIHhsYWIoIlBvcnRpb24gb2YgTWFpbiBSb290IExlbmd0aCAoJSkiKSAKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCA8LSBMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0ICsgc3RhdF9jb21wYXJlX21lYW5zKGFlcyhncm91cCA9IGNvbmQpLCBsYWJlbCA9ICJwLnNpZ25pZiIsIG1ldGhvZCA9ICJ0LnRlc3QiLCBoaWRlLm5zID0gVCkKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNApgYGAKCmBgYHtyfQpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCA8LSBnZ3Bsb3QoZGF0YT1tTFJubywgYWVzKHg9IHBlcmMub2YuTVJMLCB5PUxSbm8sIGdyb3VwID0gcm9vdF9uYW1lLCBjb2xvciA9IGNvbmQpKSAKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDQgPC0gTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDQgKyBnZW9tX2xpbmUoYWxwaGEgPSAwLjEpICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJkb2RnZXJibHVlMyIsICJ0b21hdG8xIikpIApMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCArIHN0YXRfc3VtbWFyeShnZW9tID0gInJpYmJvbiIsIGxpbmV0eXBlPTAsIGZ1bi5kYXRhID0gbWVhbl9jbF9ub3JtYWwsIGFlcyhncm91cD0gY29uZCksIGFscGhhID0gMC4yKSArIGdndGl0bGUoIjQgRGF5cyBBZnRlciBTdHJlc3MiKQpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKyBsYWJzKGNvbG9yID0gIlRyZWF0bWVudCIpCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2Q0IDwtIExSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2Q0ICsgeWxhYigiTGF0ZXJhbCBSb290IG51bWJlciIpICsgeGxhYigiUG9ydGlvbiBvZiBNYWluIFJvb3QgTGVuZ3RoICglKSIpIApMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNCArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2Q0CmBgYAoKYWxsIGdvb2QgLSBidXQgSSB0aGluayBpdCB3b3VsZCBiZSBiZXR0ZXIgdG8gY2FsY3VsYXRlIHRoZSBhYm92ZSBhcyAlb2YgTFJMIG9yICVMUm5vIHBlciBwbGFudCAtIHRoZW4gd2UgY2FuIGdldCBiZXR0ZXIgaWRlYSBmb3IgY2x1c3RlcmluZzoKCmBgYHtyfQpjb2xuYW1lcyhkYXk0KQpMUm5vX3BlcmMgPC0gZGF5NFssYygxOjgsNDg6NTcpXQpMUkxfcGVyYyA8LSBkYXk0WyxjKDE6OCwzODo0NyldCmhlYWQoTFJub19wZXJjKQpoZWFkKExSTF9wZXJjKQpgYGAKCgpgYGB7cn0KbUxSbm9fcGVyYyA8LSBtZWx0KExSbm9fcGVyYywgdmFsdWUubmFtZSA9ICJMUm5vLnBlcmMiKQptTFJMX3BlcmMgPC0gbWVsdChMUkxfcGVyYywgdmFsdWUubmFtZSA9ICJMUkwucGVyYyIpCgpoZWFkKG1MUm5vX3BlcmMpCmhlYWQobUxSTF9wZXJjKQp1bmlxdWUobUxSbm9fcGVyYyR2YXJpYWJsZSkKCm1MUm5vX3BlcmMkdmFyaWFibGUgPC0gZ3N1YigiTFJub18iLCAiIiwgbUxSbm9fcGVyYyR2YXJpYWJsZSkKbUxSTF9wZXJjJHZhcmlhYmxlIDwtIGdzdWIoIkxSTF8iLCAiIiwgbUxSTF9wZXJjJHZhcmlhYmxlKQoKbUxSbm9fcGVyYyR2YXJpYWJsZSA8LSBnc3ViKCJfcGVyYyIsICIiLCBtTFJub19wZXJjJHZhcmlhYmxlKQptTFJMX3BlcmMkdmFyaWFibGUgPC0gZ3N1YigiX3BlcmMiLCAiIiwgbUxSTF9wZXJjJHZhcmlhYmxlKQoKbUxSbm9fcGVyYyR2YXJpYWJsZSA8LSBhcy5udW1lcmljKG1MUm5vX3BlcmMkdmFyaWFibGUpCm1MUkxfcGVyYyR2YXJpYWJsZSA8LSBhcy5udW1lcmljKG1MUkxfcGVyYyR2YXJpYWJsZSkKCmNvbG5hbWVzKG1MUm5vX3BlcmMpWzldIDwtICJwZXJjLm9mLk1STCIKY29sbmFtZXMobUxSTF9wZXJjKVs5XSA8LSAicGVyYy5vZi5NUkwiCmhlYWQobUxSbm9fcGVyYykKaGVhZChtTFJMX3BlcmMpCmBgYAoKT0sgLSBub3cgbGV0J3MgcmVjYWxjdWxhdGUgdGhlc2UgZ3JhcGhzOgoKYGBge3J9CkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYyA8LSBnZ3Bsb3QoZGF0YT1tTFJMX3BlcmMsIGFlcyh4PSBwZXJjLm9mLk1STCwgeT1MUkwucGVyYywgZ3JvdXAgPSByb290X25hbWUsIGNvbG9yID0gY29uZCkpIApMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0X3BlcmMgPC0gTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNF9wZXJjICsgZ2VvbV9saW5lKGFscGhhID0gMC4xKSArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiZG9kZ2VyYmx1ZTMiLCAidG9tYXRvMSIpKSAKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNF9wZXJjIDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYyArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0X3BlcmMgPC0gTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNF9wZXJjICsgc3RhdF9zdW1tYXJ5KGdlb20gPSAicmliYm9uIiwgbGluZXR5cGU9MCwgZnVuLmRhdGEgPSBtZWFuX2NsX25vcm1hbCwgYWVzKGdyb3VwPSBjb25kKSwgYWxwaGEgPSAwLjIpICsgZ2d0aXRsZSgiNCBEYXlzIEFmdGVyIFN0cmVzcyIpCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYyA8LSBMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0X3BlcmMgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsgbGFicyhjb2xvciA9ICJUcmVhdG1lbnQiKQpMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0X3BlcmMgPC0gTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNF9wZXJjICsgeWxhYigiTGF0ZXJhbCBSb290IExlbmd0aCAoZnJhY3Rpb24gb2YgdG90YWwgTFJMKSIpICsgeGxhYigiUG9ydGlvbiBvZiBNYWluIFJvb3QgTGVuZ3RoICglKSIpIApMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2Q0X3BlcmMgPC0gTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNF9wZXJjICsgc3RhdF9jb21wYXJlX21lYW5zKGFlcyhncm91cCA9IGNvbmQpLCBsYWJlbCA9ICJwLnNpZ25pZiIsIG1ldGhvZCA9ICJ0LnRlc3QiLCBoaWRlLm5zID0gVCkKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNF9wZXJjCgoKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYyA8LSBnZ3Bsb3QoZGF0YT1tTFJub19wZXJjLCBhZXMoeD0gcGVyYy5vZi5NUkwsIHk9TFJuby5wZXJjLCBncm91cCA9IHJvb3RfbmFtZSwgY29sb3IgPSBjb25kKSkgCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2Q0X3BlcmMgPC0gTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYyArIGdlb21fbGluZShhbHBoYSA9IDAuMSkgKyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImRvZGdlcmJsdWUzIiwgInRvbWF0bzEiKSkgCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2Q0X3BlcmMgPC0gTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYyArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNF9wZXJjIDwtIExSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2Q0X3BlcmMgKyBzdGF0X3N1bW1hcnkoZ2VvbSA9ICJyaWJib24iLCBsaW5ldHlwZT0wLCBmdW4uZGF0YSA9IG1lYW5fY2xfbm9ybWFsLCBhZXMoZ3JvdXA9IGNvbmQpLCBhbHBoYSA9IDAuMikgKyBnZ3RpdGxlKCI0IERheXMgQWZ0ZXIgU3RyZXNzIikKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYyA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNF9wZXJjICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrIGxhYnMoY29sb3IgPSAiVHJlYXRtZW50IikKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYyA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNF9wZXJjICsgeWxhYigiTGF0ZXJhbCBSb290IG51bWJlciAoZnJhY3Rpb24gb2YgdG90YWwgTFIgIykiKSArIHhsYWIoIlBvcnRpb24gb2YgTWFpbiBSb290IExlbmd0aCAoJSkiKSAKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYyA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kNF9wZXJjICsgc3RhdF9jb21wYXJlX21lYW5zKGFlcyhncm91cCA9IGNvbmQpLCBsYWJlbCA9ICJwLnNpZ25pZiIsIG1ldGhvZCA9ICJ0LnRlc3QiLCBoaWRlLm5zID0gVCkKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYwpgYGAKT0sgLSBzbyB0aGUgcGVyY2VudGFnZSBvZiBMUkwgaXMgZGVmaW5pdGVseSBtb3JlIGluZm9ybWF0aXZlLiBMZXQncyBoYXZlIGEgbG9vayBob3cgaXQgbG9va3MgaW4gZWFybGllciBkYXlzOgoKIyMjIDMgZGF5cyBhZnRlciBzdHJlc3MKCmBgYHtyfQpkYXkzIDwtIHN1YnNldChhbGxfTVIzLCBhbGxfTVIzJERBUyA9PSAzKQpMUm5vX3BlcmMgPC0gZGF5M1ssYygxOjgsNDg6NTcpXQpMUkxfcGVyYyA8LSBkYXkzWyxjKDE6OCwzODo0NyldCm1MUm5vX3BlcmMgPC0gbWVsdChMUm5vX3BlcmMsIHZhbHVlLm5hbWUgPSAiTFJuby5wZXJjIikKbUxSTF9wZXJjIDwtIG1lbHQoTFJMX3BlcmMsIHZhbHVlLm5hbWUgPSAiTFJMLnBlcmMiKQoKbUxSbm9fcGVyYyR2YXJpYWJsZSA8LSBnc3ViKCJMUm5vXyIsICIiLCBtTFJub19wZXJjJHZhcmlhYmxlKQptTFJMX3BlcmMkdmFyaWFibGUgPC0gZ3N1YigiTFJMXyIsICIiLCBtTFJMX3BlcmMkdmFyaWFibGUpCgptTFJub19wZXJjJHZhcmlhYmxlIDwtIGdzdWIoIl9wZXJjIiwgIiIsIG1MUm5vX3BlcmMkdmFyaWFibGUpCm1MUkxfcGVyYyR2YXJpYWJsZSA8LSBnc3ViKCJfcGVyYyIsICIiLCBtTFJMX3BlcmMkdmFyaWFibGUpCgptTFJub19wZXJjJHZhcmlhYmxlIDwtIGFzLm51bWVyaWMobUxSbm9fcGVyYyR2YXJpYWJsZSkKbUxSTF9wZXJjJHZhcmlhYmxlIDwtIGFzLm51bWVyaWMobUxSTF9wZXJjJHZhcmlhYmxlKQoKY29sbmFtZXMobUxSbm9fcGVyYylbOV0gPC0gInBlcmMub2YuTVJMIgpjb2xuYW1lcyhtTFJMX3BlcmMpWzldIDwtICJwZXJjLm9mLk1STCIKCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYyA8LSBnZ3Bsb3QoZGF0YT1tTFJMX3BlcmMsIGFlcyh4PSBwZXJjLm9mLk1STCwgeT1MUkwucGVyYywgZ3JvdXAgPSByb290X25hbWUsIGNvbG9yID0gY29uZCkpIApMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMgPC0gTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kM19wZXJjICsgZ2VvbV9saW5lKGFscGhhID0gMC4xKSArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiZG9kZ2VyYmx1ZTMiLCAidG9tYXRvMSIpKSArIHlsaW0oMCwxKQpMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMgPC0gTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kM19wZXJjICsgc3RhdF9zdW1tYXJ5KGZ1bi55PW1lYW4sIGFlcyhncm91cD0gY29uZCksICBzaXplPTAuNywgZ2VvbT0ibGluZSIsIGxpbmV0eXBlID0gImRhc2hlZCIpCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYyA8LSBMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMgKyBzdGF0X3N1bW1hcnkoZ2VvbSA9ICJyaWJib24iLCBsaW5ldHlwZT0wLCBmdW4uZGF0YSA9IG1lYW5fY2xfbm9ybWFsLCBhZXMoZ3JvdXA9IGNvbmQpLCBhbHBoYSA9IDAuMikgKyBnZ3RpdGxlKCIzIERheXMgQWZ0ZXIgU3RyZXNzIikKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kM19wZXJjIDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYyArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKyBsYWJzKGNvbG9yID0gIlRyZWF0bWVudCIpCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYyA8LSBMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMgKyB5bGFiKCJMYXRlcmFsIFJvb3QgTGVuZ3RoIChmcmFjdGlvbiBvZiB0b3RhbCBMUkwpIikgKyB4bGFiKCJQb3J0aW9uIG9mIE1haW4gUm9vdCBMZW5ndGggKCUpIikgCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYyA8LSBMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMgKyBzdGF0X2NvbXBhcmVfbWVhbnMoYWVzKGdyb3VwID0gY29uZCksIGxhYmVsID0gInAuc2lnbmlmIiwgbWV0aG9kID0gInQudGVzdCIsIGhpZGUubnMgPSBUKQpMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMKCgpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kM19wZXJjIDwtIGdncGxvdChkYXRhPW1MUm5vX3BlcmMsIGFlcyh4PSBwZXJjLm9mLk1STCwgeT1MUm5vLnBlcmMsIGdyb3VwID0gcm9vdF9uYW1lLCBjb2xvciA9IGNvbmQpKSAKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYyA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kM19wZXJjICsgZ2VvbV9saW5lKGFscGhhID0gMC4xKSArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiZG9kZ2VyYmx1ZTMiLCAidG9tYXRvMSIpKSArIHlsaW0oMCwxKQpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kM19wZXJjIDwtIExSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMgKyBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgYWVzKGdyb3VwPSBjb25kKSwgIHNpemU9MC43LCBnZW9tPSJsaW5lIiwgbGluZXR5cGUgPSAiZGFzaGVkIikKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYyA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kM19wZXJjICsgc3RhdF9zdW1tYXJ5KGdlb20gPSAicmliYm9uIiwgbGluZXR5cGU9MCwgZnVuLmRhdGEgPSBtZWFuX2NsX25vcm1hbCwgYWVzKGdyb3VwPSBjb25kKSwgYWxwaGEgPSAwLjIpICsgZ2d0aXRsZSgiMyBEYXlzIEFmdGVyIFN0cmVzcyIpCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMgPC0gTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYyArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKyBsYWJzKGNvbG9yID0gIlRyZWF0bWVudCIpCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMgPC0gTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYyArIHlsYWIoIkxhdGVyYWwgUm9vdCBudW1iZXIgKGZyYWN0aW9uIG9mIHRvdGFsIExSICMpIikgKyB4bGFiKCJQb3J0aW9uIG9mIE1haW4gUm9vdCBMZW5ndGggKCUpIikgCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMgPC0gTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYyArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QzX3BlcmMKYGBgCgoKYGBge3J9CmRheTIgPC0gc3Vic2V0KGFsbF9NUjMsIGFsbF9NUjMkREFTID09IDIpCkxSbm9fcGVyYyA8LSBkYXkyWyxjKDE6OCw0ODo1NyldCkxSTF9wZXJjIDwtIGRheTJbLGMoMTo4LDM4OjQ3KV0KbUxSbm9fcGVyYyA8LSBtZWx0KExSbm9fcGVyYywgdmFsdWUubmFtZSA9ICJMUm5vLnBlcmMiKQptTFJMX3BlcmMgPC0gbWVsdChMUkxfcGVyYywgdmFsdWUubmFtZSA9ICJMUkwucGVyYyIpCgptTFJub19wZXJjJHZhcmlhYmxlIDwtIGdzdWIoIkxSbm9fIiwgIiIsIG1MUm5vX3BlcmMkdmFyaWFibGUpCm1MUkxfcGVyYyR2YXJpYWJsZSA8LSBnc3ViKCJMUkxfIiwgIiIsIG1MUkxfcGVyYyR2YXJpYWJsZSkKCm1MUm5vX3BlcmMkdmFyaWFibGUgPC0gZ3N1YigiX3BlcmMiLCAiIiwgbUxSbm9fcGVyYyR2YXJpYWJsZSkKbUxSTF9wZXJjJHZhcmlhYmxlIDwtIGdzdWIoIl9wZXJjIiwgIiIsIG1MUkxfcGVyYyR2YXJpYWJsZSkKCm1MUm5vX3BlcmMkdmFyaWFibGUgPC0gYXMubnVtZXJpYyhtTFJub19wZXJjJHZhcmlhYmxlKQptTFJMX3BlcmMkdmFyaWFibGUgPC0gYXMubnVtZXJpYyhtTFJMX3BlcmMkdmFyaWFibGUpCgpjb2xuYW1lcyhtTFJub19wZXJjKVs5XSA8LSAicGVyYy5vZi5NUkwiCmNvbG5hbWVzKG1MUkxfcGVyYylbOV0gPC0gInBlcmMub2YuTVJMIgoKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMl9wZXJjIDwtIGdncGxvdChkYXRhPW1MUkxfcGVyYywgYWVzKHg9IHBlcmMub2YuTVJMLCB5PUxSTC5wZXJjLCBncm91cCA9IHJvb3RfbmFtZSwgY29sb3IgPSBjb25kKSkgCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYyA8LSBMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QyX3BlcmMgKyBnZW9tX2xpbmUoYWxwaGEgPSAwLjEpICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJkb2RnZXJibHVlMyIsICJ0b21hdG8xIikpICsgeWxpbSgwLDEpCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYyA8LSBMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QyX3BlcmMgKyBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgYWVzKGdyb3VwPSBjb25kKSwgIHNpemU9MC43LCBnZW9tPSJsaW5lIiwgbGluZXR5cGUgPSAiZGFzaGVkIikKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMl9wZXJjIDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYyArIHN0YXRfc3VtbWFyeShnZW9tID0gInJpYmJvbiIsIGxpbmV0eXBlPTAsIGZ1bi5kYXRhID0gbWVhbl9jbF9ub3JtYWwsIGFlcyhncm91cD0gY29uZCksIGFscGhhID0gMC4yKSArIGdndGl0bGUoIjIgRGF5cyBBZnRlciBTdHJlc3MiKQpMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QyX3BlcmMgPC0gTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMl9wZXJjICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrIGxhYnMoY29sb3IgPSAiVHJlYXRtZW50IikKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMl9wZXJjIDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYyArIHlsYWIoIkxhdGVyYWwgUm9vdCBMZW5ndGggKGZyYWN0aW9uIG9mIHRvdGFsIExSTCkiKSArIHhsYWIoIlBvcnRpb24gb2YgTWFpbiBSb290IExlbmd0aCAoJSkiKSAKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMl9wZXJjIDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYyArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYwoKCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QyX3BlcmMgPC0gZ2dwbG90KGRhdGE9bUxSbm9fcGVyYywgYWVzKHg9IHBlcmMub2YuTVJMLCB5PUxSbm8ucGVyYywgZ3JvdXAgPSByb290X25hbWUsIGNvbG9yID0gY29uZCkpIApMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMl9wZXJjIDwtIExSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QyX3BlcmMgKyBnZW9tX2xpbmUoYWxwaGEgPSAwLjEpICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJkb2RnZXJibHVlMyIsICJ0b21hdG8xIikpICsgeWxpbSgwLDEpCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QyX3BlcmMgPC0gTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYyArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMl9wZXJjIDwtIExSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QyX3BlcmMgKyBzdGF0X3N1bW1hcnkoZ2VvbSA9ICJyaWJib24iLCBsaW5ldHlwZT0wLCBmdW4uZGF0YSA9IG1lYW5fY2xfbm9ybWFsLCBhZXMoZ3JvdXA9IGNvbmQpLCBhbHBoYSA9IDAuMikgKyBnZ3RpdGxlKCIyIERheXMgQWZ0ZXIgU3RyZXNzIikKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYyA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMl9wZXJjICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrIGxhYnMoY29sb3IgPSAiVHJlYXRtZW50IikKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYyA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMl9wZXJjICsgeWxhYigiTGF0ZXJhbCBSb290IG51bWJlciAoZnJhY3Rpb24gb2YgdG90YWwgTFIgIykiKSArIHhsYWIoIlBvcnRpb24gb2YgTWFpbiBSb290IExlbmd0aCAoJSkiKSAKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYyA8LSBMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMl9wZXJjICsgc3RhdF9jb21wYXJlX21lYW5zKGFlcyhncm91cCA9IGNvbmQpLCBsYWJlbCA9ICJwLnNpZ25pZiIsIG1ldGhvZCA9ICJ0LnRlc3QiLCBoaWRlLm5zID0gVCkKTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYwpgYGAKCmBgYHtyfQpkYXkxIDwtIHN1YnNldChhbGxfTVIzLCBhbGxfTVIzJERBUyA9PSAxKQpMUm5vX3BlcmMgPC0gZGF5MVssYygxOjgsNDg6NTcpXQpMUkxfcGVyYyA8LSBkYXkxWyxjKDE6OCwzODo0NyldCm1MUm5vX3BlcmMgPC0gbWVsdChMUm5vX3BlcmMsIHZhbHVlLm5hbWUgPSAiTFJuby5wZXJjIikKbUxSTF9wZXJjIDwtIG1lbHQoTFJMX3BlcmMsIHZhbHVlLm5hbWUgPSAiTFJMLnBlcmMiKQoKbUxSbm9fcGVyYyR2YXJpYWJsZSA8LSBnc3ViKCJMUm5vXyIsICIiLCBtTFJub19wZXJjJHZhcmlhYmxlKQptTFJMX3BlcmMkdmFyaWFibGUgPC0gZ3N1YigiTFJMXyIsICIiLCBtTFJMX3BlcmMkdmFyaWFibGUpCgptTFJub19wZXJjJHZhcmlhYmxlIDwtIGdzdWIoIl9wZXJjIiwgIiIsIG1MUm5vX3BlcmMkdmFyaWFibGUpCm1MUkxfcGVyYyR2YXJpYWJsZSA8LSBnc3ViKCJfcGVyYyIsICIiLCBtTFJMX3BlcmMkdmFyaWFibGUpCgptTFJub19wZXJjJHZhcmlhYmxlIDwtIGFzLm51bWVyaWMobUxSbm9fcGVyYyR2YXJpYWJsZSkKbUxSTF9wZXJjJHZhcmlhYmxlIDwtIGFzLm51bWVyaWMobUxSTF9wZXJjJHZhcmlhYmxlKQoKY29sbmFtZXMobUxSbm9fcGVyYylbOV0gPC0gInBlcmMub2YuTVJMIgpjb2xuYW1lcyhtTFJMX3BlcmMpWzldIDwtICJwZXJjLm9mLk1STCIKCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDFfcGVyYyA8LSBnZ3Bsb3QoZGF0YT1tTFJMX3BlcmMsIGFlcyh4PSBwZXJjLm9mLk1STCwgeT1MUkwucGVyYywgZ3JvdXAgPSByb290X25hbWUsIGNvbG9yID0gY29uZCkpIApMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgPC0gTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjICsgZ2VvbV9saW5lKGFscGhhID0gMC4xKSArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygiZG9kZ2VyYmx1ZTMiLCAidG9tYXRvMSIpKSArIHlsaW0oMCwxKQpMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgPC0gTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjICsgc3RhdF9zdW1tYXJ5KGZ1bi55PW1lYW4sIGFlcyhncm91cD0gY29uZCksICBzaXplPTAuNywgZ2VvbT0ibGluZSIsIGxpbmV0eXBlID0gImRhc2hlZCIpCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDFfcGVyYyA8LSBMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgKyBzdGF0X3N1bW1hcnkoZ2VvbSA9ICJyaWJib24iLCBsaW5ldHlwZT0wLCBmdW4uZGF0YSA9IG1lYW5fY2xfbm9ybWFsLCBhZXMoZ3JvdXA9IGNvbmQpLCBhbHBoYSA9IDAuMikgKyBnZ3RpdGxlKCIxIERheSBBZnRlciBTdHJlc3MiKQpMUkxfZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgPC0gTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikrIGxhYnMoY29sb3IgPSAiVHJlYXRtZW50IikKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjIDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDFfcGVyYyArIHlsYWIoIkxhdGVyYWwgUm9vdCBMZW5ndGggKGZyYWN0aW9uIG9mIHRvdGFsIExSTCkiKSArIHhsYWIoIlBvcnRpb24gb2YgTWFpbiBSb290IExlbmd0aCAoJSkiKSAKTFJMX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjIDwtIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDFfcGVyYyArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCkxSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDFfcGVyYwoKCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgPC0gZ2dwbG90KGRhdGE9bUxSbm9fcGVyYywgYWVzKHg9IHBlcmMub2YuTVJMLCB5PUxSbm8ucGVyYywgZ3JvdXAgPSByb290X25hbWUsIGNvbG9yID0gY29uZCkpIApMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjIDwtIExSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgKyBnZW9tX2xpbmUoYWxwaGEgPSAwLjEpICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJkb2RnZXJibHVlMyIsICJ0b21hdG8xIikpICsgeWxpbSgwLDEpCkxSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgPC0gTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDFfcGVyYyArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjIDwtIExSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgKyBzdGF0X3N1bW1hcnkoZ2VvbSA9ICJyaWJib24iLCBsaW5ldHlwZT0wLCBmdW4uZGF0YSA9IG1lYW5fY2xfbm9ybWFsLCBhZXMoZ3JvdXA9IGNvbmQpLCBhbHBoYSA9IDAuMikgKyBnZ3RpdGxlKCIxIERheSBBZnRlciBTdHJlc3MiKQpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjIDwtIExSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSsgbGFicyhjb2xvciA9ICJUcmVhdG1lbnQiKQpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjIDwtIExSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgKyB5bGFiKCJMYXRlcmFsIFJvb3QgbnVtYmVyIChmcmFjdGlvbiBvZiB0b3RhbCBMUiAjKSIpICsgeGxhYigiUG9ydGlvbiBvZiBNYWluIFJvb3QgTGVuZ3RoICglKSIpIApMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjIDwtIExSbm9fZGlzdHJpYnV0aW9uX2dyYXBoX2QxX3BlcmMgKyBzdGF0X2NvbXBhcmVfbWVhbnMoYWVzKGdyb3VwID0gY29uZCksIGxhYmVsID0gInAuc2lnbmlmIiwgbWV0aG9kID0gInQudGVzdCIsIGhpZGUubnMgPSBUKQpMUm5vX2Rpc3RyaWJ1dGlvbl9ncmFwaF9kMV9wZXJjCmBgYAoKb2sgLSBtYXliZSBsZXQncyBjb21iaW5lIHRoZXNlIGdyYXBocyBpbnRvIGEgZmlndXJlIHRodXMgZmFyOgoKYGBge3J9CmxpYnJhcnkoY293cGxvdCkKcGRmKCJGaWcuTGF0ZXJhbF9yb290X2Rpc3RyaWJ1dGlvbl9hY3Jvc3NfTVJMX0RBUzFfREFTNF9CaWcwMV90b19CaWcwNC5wZGYiLCBoZWlnaHQgPSAyMCwgd2lkdGggPSAxNSkKcGxvdF9ncmlkKExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDFfcGVyYywgTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDFfcGVyYywKICAgICAgICAgIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYywgTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDJfcGVyYywKICAgICAgICAgIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYywgTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDNfcGVyYywKICAgICAgICAgIExSTF9kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYywgTFJub19kaXN0cmlidXRpb25fZ3JhcGhfZDRfcGVyYywgbmNvbD0yLCBsYWJlbHMgPSAiQVVUTyIpCmRldi5vZmYoKQpgYGAKCgoKIyBDYWxjdWxhdGluZyBncm93dGggcmF0ZXMgZm9yIGVhY2ggcGxhbnQ6CgpPSyAtIHNvIG5vdyB3ZSBoYXZlIGFsbCB0aGUgZGF0YSBvcmdhbml6ZWQgYW5kIGV2ZXJ5dGhpbmcgc2VlbXMgdG8gbG9vayBwcmV0dHkgc2FuZSAtIGxldCdzIHN0YXJ0IGNhbGN1bGF0aW5nIHRoZSBncm93dGggcmF0ZSBvZiBhTFJMLCBMUiMgYW5kIE1SLiBUaGUgcHJvYmxlbSBpcyB0aGF0IGluIHNvbWUgY2FzZXMgLSB0aGUgTVIgZ3JldyBpbnRvIHRoZSBwbGF0ZSAtIGFuZCB3ZSBkaWRudCBjb250aW51ZSB0cmFjaW5nIGl0IC0gc28gdGhlIGxlbmd0aCBpcyBnZXR0aW5nIHN0YWxlZC4gU28gLSBpbiB0aGVzZSBjYXNlcyAtIEkgd291bGQgbGlrZSB0byBjYWxjdWxhdGUgdGhlIGdyb3d0aCByYXRlIG9ubHkgb3ZlciB0aGUgcGVyaW9kIHdoZXJlIHRoZSBzaXplIG9mIHRoZSByb290IGlzIGFjdHVhbGx5IGluY3JlYXNpbmcuIFNvOgoKRmlyc3QgLSBzZXQgdGhlICJkYXkiIGFkIG51bWVyaWMgdmFyaWFibGUgLSBiZWNhdXNlIHRoaXMgd2lsbCBsYXRlciBjb21lIGFuZCBiaXRlIHVzIGluIG91ciBhc3NlczoKCmBgYHtyfQphbGxfTVIzJERBUyA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihhbGxfTVIzJERBUykpCmhlYWQoYWxsX01SMykKYGBgCiMjIEVzdGFibGlzaGluZyBjYWxjdWxhdGlvbnMKClNlY29uZCAtIGlzb2xhdGUgb25lIHBsYW50IGZyb20gdGhlIGRhdGFzZXQsIHNvcnQgcGVyIGRheSwgYW5kIG1hcmsgd2hpY2ggb2YgdGhlIHZhbHVlcyBmb3IgTVIgYXJlIGR1cGxpY2F0ZXM6CmBgYHtyfQp0ZW1wMSA8LSBzdWJzZXQoYWxsX01SMywgYWxsX01SMyRyb290ID09IHVuaXF1ZShhbGxfTVIzJHJvb3QpWzEwMF0pCnRlbXAyIDwtIHRlbXAxW29yZGVyKHRlbXAxJERBUyksXQpoZWFkKHRlbXAyKQoKdGVtcDIkTVJkb3VibGUgPC0gIm5vIgpmb3IoaSBpbiAyOjUpewogaWYodGVtcDIkTVJMW2ldID09IHRlbXAyJE1STFtpLTFdKXsKICB0ZW1wMiRNUmRvdWJsZVtpXSA8LSAieWVzIiAgIAogfSAKICBlbHNlewogIHRlbXAyJE1SZG91YmxlW2ldIDwtICJubyIgICAKIH0gCn0KCnRlbXAzIDwtIHN1YnNldCh0ZW1wMiwgdGVtcDIkTVJkb3VibGUgPT0gIm5vIikKdGVtcDMKYGBgCgpOb3cgdGhhdCB3ZSBoYXZlIHRoZSBkYXRhc2V0IHdpdGhvdXQgZHVwbGljYXRlZCB2YWx1ZXMgLSBsZXQncyBjYWxjdWxhdGUgTVIgZ3Jvd3RoIHJhdGUgdXNpbmcgbGluZWFyIGZ1bmN0aW9uOgoKYGBge3J9CnBsb3QodGVtcDMkTVJMIH4gdGVtcDMkREFTKQphYmxpbmUobG0odGVtcDMkTVJMIH4gdGVtcDMkREFTKSkKYGBgCgpMZXQncyBjaGVjayBpZiB0aGlzIGlzIGFsc28gdHJ1ZSBmb3IgI0xSOgoKYGBge3J9CnRlbXAyJExSbm9kb3VibGUgPC0gIm5vIgpmb3IoaSBpbiAyOjUpewogaWYodGVtcDIkTFJub1tpXSA9PSB0ZW1wMiRMUm5vW2ktMV0pewogIHRlbXAyJExSbm9kb3VibGVbaV0gPC0gInllcyIgICAKIH0gCiAgZWxzZXsKICB0ZW1wMiRMUm5vZG91YmxlW2ldIDwtICJubyIgICAKIH0gCn0KCnRlbXAzIDwtIHN1YnNldCh0ZW1wMiwgdGVtcDIkTFJub2RvdWJsZSA9PSAibm8iKQoKcGxvdCh0ZW1wMyRMUm5vIH4gdGVtcDMkREFTKQphYmxpbmUobG0odGVtcDMkTFJubyB+IHRlbXAzJERBUykpCmBgYAphbmQgZm9yIGFMUkw6CgpgYGB7cn0KdGVtcDIkYUxSTGRvdWJsZSA8LSAibm8iCmZvcihpIGluIDI6NSl7CiBpZih0ZW1wMiRhTFJMW2ldID09IHRlbXAyJGFMUkxbaS0xXSl7CiAgdGVtcDIkYUxSTGRvdWJsZVtpXSA8LSAieWVzIiAgIAogfSAKICBlbHNlewogIHRlbXAyJGFMUkxkb3VibGVbaV0gPC0gIm5vIiAgIAogfSAKfQp0ZW1wMgoKdGVtcDMgPC0gc3Vic2V0KHRlbXAyLCB0ZW1wMiRhTFJMZG91YmxlID09ICJubyIpCgpwbG90KHRlbXAzJGFMUkwgfiB0ZW1wMyREQVMpCmFibGluZShsbSh0ZW1wMyRhTFJMIH4gdGVtcDMkREFTKSkKYGBgCgojIyBMb29wZWQgbGluZWFyIG1vZGVsaW5nIGZvciBhbGwgUlNBIGNvbXBvbmVudHMKCkZpcnN0IC0gbGV0J3MgY29uc3RydWN0IHRoZSBkYXRhZnJhbWUgd2hpY2ggd2lsbCBob2xkIGFsbCB0aGUgZGF0YSBwb2ludHM6CgpgYGB7cn0KbmFtZXMgPC0gYyh0ZXh0PSJyb290X25hbWUiLCAiZ2Vub3R5cGUiLCAiY29uZCIsICJNUi5pbnRlcmNlcHQiLCAiTVIuZGVsdGEiLCAiTFJuby5pbnRlcmNlcHQiLCAiTFJuby5kZWx0YSIsICJhTFJMLmludGVyY2VwdCIsICJhTFJMLmRlbHRhIikKZ3Jvd3RoX2ZhY3RvcnMgPC0gZGF0YS5mcmFtZSgpCgpmb3IgKGsgaW4gbmFtZXMpIGdyb3d0aF9mYWN0b3JzW1trXV0gPC0gYXMuY2hhcmFjdGVyKCkKCmBgYAoKanVzdCBmZXcgZml4ZXM6CgpgYGB7cn0KYWxsX01SMyRyb290X25hbWU8LSBnc3ViKCIyODAwXzNfUyIsICIyODBfM19TIiwgYWxsX01SMyRyb290X25hbWUpCmFsbF9NUjMgPC0gc3Vic2V0KGFsbF9NUjMsIGFsbF9NUjMkaW1hZ2UgIT0gIl9zZXQxX2RheTFfMjAxOTA5MzBfMDkzLnJzbWwiKQphbGxfTVIzIDwtIHN1YnNldChhbGxfTVIzLCBhbGxfTVIzJGltYWdlICE9ICJfc2V0MV9kYXkxXzIwMTkwOTMwXzA5MC5yc21sIikJCmFsbF9NUjMgPC0gc3Vic2V0KGFsbF9NUjMsIGFsbF9NUjMkaW1hZ2UgIT0gIl9zZXQxX2RheTFfMjAxOTA5MzBfMDY3LnJzbWwiKQphbGxfTVIzIDwtIHN1YnNldChhbGxfTVIzLCBhbGxfTVIzJGltYWdlICE9ICJfc2V0MV9kYXkxXzIwMTkxMDA4XzA0N19GVS5yc21sIikKCmBgYAoKClRoZW4gLSBsZXQncyBsb29wIGl0IGluIGZvciBjYWxjdWxhdGluZyB0aGUgTWFpbiBSb290IGdyb3d0aCBmYWN0b3JzOgoKYGBge3J9CmZvcihlIGluIGMoMTpsZW5ndGgodW5pcXVlKGFsbF9NUjMkcm9vdF9uYW1lKSkpKXsKICB0ZW1wMSA8LSBzdWJzZXQoYWxsX01SMywgYWxsX01SMyRyb290X25hbWUgPT0gdW5pcXVlKGFsbF9NUjMkcm9vdF9uYW1lKVtlXSkKICB0ZW1wMiA8LSB0ZW1wMVtvcmRlcih0ZW1wMSREQVMpLF0KICBkaW0odGVtcDIpCiAgaWYoZGltKHRlbXAyKVsxXSA8IDIpewogICAgCiAgfQogIAogICMgTWFpbiByb290IHBhcnQKICB0ZW1wMiRNUmRvdWJsZSA8LSAibm8iCiAgZm9yKGkgaW4gMjpucm93KHRlbXAyKSl7CiAgIGlmKHRlbXAyJE1STFtpXSA9PSB0ZW1wMiRNUkxbaS0xXSl7CiAgICB0ZW1wMiRNUmRvdWJsZVtpXSA8LSAieWVzIiAgIAogICB9IAogICAgZWxzZXsKICAgIHRlbXAyJE1SZG91YmxlW2ldIDwtICJubyIgICAKICAgfSAKICB9CiAgCiAgdGVtcDIKICAjIE1haW4gUm9vdCBHcm93dGggRmFjdG9yIGNhbGN1bGF0aW9uczogCiAgdGVtcDMgPC0gc3Vic2V0KHRlbXAyLCB0ZW1wMiRNUmRvdWJsZSA9PSAibm8iKQogIG1vZGVsIDwtIGxtKHRlbXAzJE1STCB+IHRlbXAzJERBUykKICBncm93dGhfZmFjdG9yc1tlLDFdIDwtIHRlbXAzJHJvb3RfbmFtZVsxXQogIGdyb3d0aF9mYWN0b3JzW2UsMl0gPC0gdGVtcDMkZ2Vub3R5cGVbMV0KICBncm93dGhfZmFjdG9yc1tlLDNdIDwtIHRlbXAzJGNvbmRbMV0KICBncm93dGhfZmFjdG9yc1tlLDRdIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1vZGVsJGNvZWZmaWNpZW50c1tbMV1dKSkKICBncm93dGhfZmFjdG9yc1tlLDVdIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1vZGVsJGNvZWZmaWNpZW50c1tbMl1dKSkKICAKIAp9CmBgYAoKCmBgYHtyfQpkaW0oZ3Jvd3RoX2ZhY3RvcnMpCmBgYAoKR3JlYXQgLSBsZXQncyBjYWxjdWxhdGUgdGhlIExSbm8gaW5jcmVhc2UgcmF0ZSAtIHdpdGggc29tZSBzcGVjaWFsIGNvbmRpdGlvbnMgZm9yIHRoZSBsaW5lcyB3aGljaCBkb24ndCBoYXZlIGFueSBMUjoKCmBgYHtyfQpmb3IoZSBpbiAxOmxlbmd0aCh1bmlxdWUoYWxsX01SMyRyb290X25hbWUpKSl7CiAgdGVtcDEgPC0gc3Vic2V0KGFsbF9NUjMsIGFsbF9NUjMkcm9vdF9uYW1lID09IHVuaXF1ZShhbGxfTVIzJHJvb3RfbmFtZSlbZV0pCiAgdGVtcDIgPC0gdGVtcDFbb3JkZXIodGVtcDEkREFTKSxdCgogIyBMZXQncyByZW1vdmUgYWxsIE5BIGZvciBMUm5vIGFuZCBhTFJMIGluIHRlbXAyCiAgc3VwZXJfdGVtcCA8LSB0ZW1wMlssYygiREFTIiwgIkxSbm8iLCAiYUxSTCIpXQogIHRlbXAyIDwtIG5hLm9taXQoc3VwZXJfdGVtcCkKICAKICBpZihkaW0odGVtcDIpWzFdID4gMSl7CiAgICBtb2RlbCA8LSBsbSh0ZW1wMiRMUm5vIH4gdGVtcDIkREFTKQogICAgZ3Jvd3RoX2ZhY3RvcnNbZSw2XSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcihtb2RlbCRjb2VmZmljaWVudHNbWzFdXSkpCiAgICBncm93dGhfZmFjdG9yc1tlLDddIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1vZGVsJGNvZWZmaWNpZW50c1tbMl1dKSkgIAogIH0KICAjIExhdGVyYWwgUm9vdCBOdW1iZXIgSW5jcmVhc2UgY2FsY3VsYXRpb25zOgogIGVsc2V7CiAgICBncm93dGhfZmFjdG9yc1tlLDZdIDwtIDAKICAgIGdyb3d0aF9mYWN0b3JzW2UsN10gPC0gMAogIH0KfSAgCmBgYAoKU2FtZSB0aGluZyBmb3IgYUxSTDoKCmBgYHtyfQpmb3IoZSBpbiAxOmxlbmd0aCh1bmlxdWUoYWxsX01SMyRyb290X25hbWUpKSl7CiAgdGVtcDEgPC0gc3Vic2V0KGFsbF9NUjMsIGFsbF9NUjMkcm9vdF9uYW1lID09IHVuaXF1ZShhbGxfTVIzJHJvb3RfbmFtZSlbZV0pCiAgdGVtcDIgPC0gdGVtcDFbb3JkZXIodGVtcDEkREFTKSxdCgogIyBMZXQncyByZW1vdmUgYWxsIE5BIGZvciBMUm5vIGFuZCBhTFJMIGluIHRlbXAyCiAgc3VwZXJfdGVtcCA8LSB0ZW1wMlssYygiREFTIiwgIkxSbm8iLCAiYUxSTCIpXQogIHRlbXAyIDwtIG5hLm9taXQoc3VwZXJfdGVtcCkKICB0ZW1wMgogIGRpbSh0ZW1wMilbMV0KICBpZihkaW0odGVtcDIpWzFdID4gMSl7CiAgICBtb2RlbCA8LSBsbSh0ZW1wMiRhTFJMIH4gdGVtcDIkREFTKQogICAgbW9kZWwKICAgIGdyb3d0aF9mYWN0b3JzW2UsOF0gPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIobW9kZWwkY29lZmZpY2llbnRzW1sxXV0pKQogICAgZ3Jvd3RoX2ZhY3RvcnNbZSw5XSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcihtb2RlbCRjb2VmZmljaWVudHNbWzJdXSkpICAKICB9CiAgIyBMYXRlcmFsIFJvb3QgTnVtYmVyIEluY3JlYXNlIGNhbGN1bGF0aW9uczoKICBlbHNlewogICAgZ3Jvd3RoX2ZhY3RvcnNbZSw4XSA8LSAwCiAgICBncm93dGhfZmFjdG9yc1tlLDldIDwtIDAKICB9Cn0gIApgYGAKCkxldCdzIGhhdmUgYSBsb29rIGF0IHRoZSBncm93dGhfZmFjdG9ycyB0YWJsZToKCmBgYHtyfQpncm93dGhfZmFjdG9ycwptaW4oZ3Jvd3RoX2ZhY3RvcnMkTVIuZGVsdGEpCm1pbihncm93dGhfZmFjdG9ycyRMUm5vLmRlbHRhKQptaW4oZ3Jvd3RoX2ZhY3RvcnMkYUxSTC5kZWx0YSkKCm1heChncm93dGhfZmFjdG9ycyRNUi5kZWx0YSkKbWF4KGdyb3d0aF9mYWN0b3JzJExSbm8uZGVsdGEpCm1heChncm93dGhfZmFjdG9ycyRhTFJMLmRlbHRhKQoKc2FwcGx5KGdyb3d0aF9mYWN0b3JzLCBjbGFzcykKZ3Jvd3RoX2ZhY3RvcnMkTVIuZGVsdGEgPC0gYXMubnVtZXJpYyhncm93dGhfZmFjdG9ycyRNUi5kZWx0YSkKZ3Jvd3RoX2ZhY3RvcnMkTFJuby5kZWx0YSA8LSBhcy5udW1lcmljKGdyb3d0aF9mYWN0b3JzJExSbm8uZGVsdGEpCmdyb3d0aF9mYWN0b3JzJGFMUkwuZGVsdGEgPC0gYXMubnVtZXJpYyhncm93dGhfZmFjdG9ycyRhTFJMLmRlbHRhKQpgYGAKCiMjIEhpc3RvZ3JhbXMgZm9yIGdyb3d0aCByYXRlcwoKTW9zdCB2YWx1ZXMgc2VlbSB0byBiZSBpbiB0aGUgcmVhc29uYWJsZSByYW5nZSAtIGJ1dCBsZXQncyBoYXZlIGEgbG9vayBhdCB0aGUgaGlzdG9ncmFtCgpgYGB7cn0KTVIuZGVsdGFfaGlzdG8gPC0gZ2doaXN0b2dyYW0oZ3Jvd3RoX2ZhY3RvcnMsIHggPSAiTVIuZGVsdGEiLAogICAgICAgICAgICBhZGQgPSAibWVhbiIsIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgIGNvbG9yID0gImNvbmQiLCBmaWxsID0gImNvbmQiLCAKICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIpKSArIHhsYWIoIk1haW4gUm9vdCBHcm93dGggKGNtIC8gZGF5KSIpCk1SLmRlbHRhX2hpc3RvCmBgYAoKYGBge3J9CkxSbm8uZGVsdGFfaGlzdG8gPC0gZ2doaXN0b2dyYW0oZ3Jvd3RoX2ZhY3RvcnMsIHggPSAiTFJuby5kZWx0YSIsCiAgICAgICAgICAgIGFkZCA9ICJtZWFuIiwgcnVnID0gVFJVRSwKICAgICAgICAgICAgY29sb3IgPSAiY29uZCIsIGZpbGwgPSAiY29uZCIsIAogICAgICAgICAgICBwYWxldHRlID0gYygiIzAwQUZCQiIsICIjRTdCODAwIikpICsgeGxhYigiSW5jcmVhc2UgaW4gTGF0ZXJhbCBSb290IG51bWJlciAoIyBMUiAvIGRheSkiKQpMUm5vLmRlbHRhX2hpc3RvCmBgYAoKYGBge3J9CmFMUkwuZGVsdGFfaGlzdG8gPC0gZ2doaXN0b2dyYW0oZ3Jvd3RoX2ZhY3RvcnMsIHggPSAiYUxSTC5kZWx0YSIsCiAgICAgICAgICAgIGFkZCA9ICJtZWFuIiwgcnVnID0gVFJVRSwKICAgICAgICAgICAgY29sb3IgPSAiY29uZCIsIGZpbGwgPSAiY29uZCIsIAogICAgICAgICAgICBwYWxldHRlID0gYygiIzAwQUZCQiIsICIjRTdCODAwIikpICsgeGxhYigiYXZlcmFnZSBMYXRlcmFsIFJvb3QgR3Jvd3RoIChjbSAvIGRheSkiKQphTFJMLmRlbHRhX2hpc3RvCmBgYAoKYXdlc29tZSAtIGxldCdzIHNhdmUgdGhpcyBpbnRvIG9uZSBmaWd1cmUgYXMgd2VsbDoKCmBgYHtyfQpwZGYoIkZpZy5Hcm93dGhfcmF0ZXNfaGlzdG9ncmFtc19NUl9ub0xSX2FMUkwucGRmIiwgd2lkdGggPSA3LjUsIGhlaWdodCA9IDEwKQpwbG90X2dyaWQoTVIuZGVsdGFfaGlzdG8sIExSbm8uZGVsdGFfaGlzdG8sIGFMUkwuZGVsdGFfaGlzdG8sIG5jb2w9MSwgbGFiZWxzID0gIkFVVE8iKQpkZXYub2ZmKCkKYGBgCgojIyByZXByb2R1Y2liaWxpdHkgd2l0aGluIGFjY2Vzc2lvbnMgZm9yIGdyb3d0aCByYXRlczoKCmxldCdzIGhhdmUgYSBsb29rIHdoYXQgaXMgdGhlIGRpdmVyc2l0eSBvZiBncm93dGggcmF0ZXMgd2l0aGluIGFjY2Vzc2lvbnM6CgpgYGB7cn0KZ3JhbmQubWVhbnMgPC0gYWdncmVnYXRlKE1SLmRlbHRhIH4gY29uZCwgZGF0YSA9IGdyb3d0aF9mYWN0b3JzLCBGVU4gPSBtZWFuKQpncmFuZC5tZWFucwoKdW5pcXVlKGdyb3d0aF9mYWN0b3JzJGdlbm90eXBlKQoKTVIuZGVsdGFfcF9nZW5vIDwtIGdnZXJyb3JwbG90KGdyb3d0aF9mYWN0b3JzLCB5ID0gIk1SLmRlbHRhIiwgeCA9ICJnZW5vdHlwZSIsIGZpbGw9Imdlbm90eXBlIiwgY29sb3I9Imdlbm90eXBlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGZhY2V0LmJ5ID0gYygiY29uZCIpLCBuY29sPTEsCiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2Nfc3RhdCA9ICJtZWFuX3NkIiwgYWRkID0gImppdHRlciIsIAogICAgICAgICAgICAgICAgICAgICAgICBhZGQucGFyYW1zID0gbGlzdChjb2xvciA9ICJkYXJrZ3JheSIpLAogICAgICAgICAgICAgICAgICAgICAgICB4bGFiPSJHZW5vdHlwZSIsIHlsYWI9Ik1haW4gUm9vdCBHcm93dGggKGNtIC8gZGF5KSIpIApNUi5kZWx0YV9wX2dlbm8gPC0gTVIuZGVsdGFfcF9nZW5vICsgZ2VvbV9obGluZSgKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZ3JhbmQubWVhbnMsIGFlcyh5aW50ZXJjZXB0ID0gTVIuZGVsdGEpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlID0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cCA9ICJjb25kIikKTVIuZGVsdGFfcF9nZW5vIDwtIE1SLmRlbHRhX3BfZ2VubyArIHJyZW1vdmUoImxlZ2VuZCIpICsgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZD0idC50ZXN0IiwgcmVmLmdyb3VwID0gIi5hbGwuIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAicC5zaWduaWYiLCBoaWRlLm5zID0gVCkKTVIuZGVsdGFfcF9nZW5vCmBgYApgYGB7cn0KZ3JhbmQubWVhbnMgPC0gYWdncmVnYXRlKExSbm8uZGVsdGEgfiBjb25kLCBkYXRhID0gZ3Jvd3RoX2ZhY3RvcnMsIEZVTiA9IG1lYW4pCmdyYW5kLm1lYW5zCgpMUm5vLmRlbHRhX3BfZ2VubyA8LSBnZ2Vycm9ycGxvdChncm93dGhfZmFjdG9ycywgeSA9ICJMUm5vLmRlbHRhIiwgeCA9ICJnZW5vdHlwZSIsIGZpbGw9Imdlbm90eXBlIiwgY29sb3I9Imdlbm90eXBlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGZhY2V0LmJ5ID0gYygiY29uZCIpLCBuY29sPTEsCiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2Nfc3RhdCA9ICJtZWFuX3NkIiwgYWRkID0gImppdHRlciIsIAogICAgICAgICAgICAgICAgICAgICAgICBhZGQucGFyYW1zID0gbGlzdChjb2xvciA9ICJkYXJrZ3JheSIpLAogICAgICAgICAgICAgICAgICAgICAgICB4bGFiPSJHZW5vdHlwZSIsIHlsYWI9IkluY3JlYXNlIGluIExSIG51bWJlciAoIyBMUiAvIGRheSkiKSAKTFJuby5kZWx0YV9wX2dlbm8gPC0gTFJuby5kZWx0YV9wX2dlbm8gKyBnZW9tX2hsaW5lKAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBncmFuZC5tZWFucywgYWVzKHlpbnRlcmNlcHQgPSBMUm5vLmRlbHRhKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAiY29uZCIpCkxSbm8uZGVsdGFfcF9nZW5vIDwtIExSbm8uZGVsdGFfcF9nZW5vICsgcnJlbW92ZSgibGVnZW5kIikgKyBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kPSJ0LnRlc3QiLCByZWYuZ3JvdXAgPSAiLmFsbC4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJwLnNpZ25pZiIsIGhpZGUubnMgPSBUKQpMUm5vLmRlbHRhX3BfZ2VubwpgYGAKCmBgYHtyfQpncmFuZC5tZWFucyA8LSBhZ2dyZWdhdGUoYUxSTC5kZWx0YSB+IGNvbmQsIGRhdGEgPSBncm93dGhfZmFjdG9ycywgRlVOID0gbWVhbikKZ3JhbmQubWVhbnMKCmFMUkwuZGVsdGFfcF9nZW5vIDwtIGdnZXJyb3JwbG90KGdyb3d0aF9mYWN0b3JzLCB5ID0gImFMUkwuZGVsdGEiLCB4ID0gImdlbm90eXBlIiwgZmlsbD0iZ2Vub3R5cGUiLCBjb2xvcj0iZ2Vub3R5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgZmFjZXQuYnkgPSBjKCJjb25kIiksIG5jb2w9MSwKICAgICAgICAgICAgICAgICAgICAgICAgZGVzY19zdGF0ID0gIm1lYW5fc2QiLCBhZGQgPSAiaml0dGVyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGFkZC5wYXJhbXMgPSBsaXN0KGNvbG9yID0gImRhcmtncmF5IiksCiAgICAgICAgICAgICAgICAgICAgICAgIHhsYWI9Ikdlbm90eXBlIiwgeWxhYj0iYXZlcmFnZSBMYXRlcmFsIFJvb3QgR3Jvd3RoIChjbSAvIGRheSkiKSAKYUxSTC5kZWx0YV9wX2dlbm8gPC0gYUxSTC5kZWx0YV9wX2dlbm8gKyBnZW9tX2hsaW5lKAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBncmFuZC5tZWFucywgYWVzKHlpbnRlcmNlcHQgPSBhTFJMLmRlbHRhKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5ldHlwZSA9IDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSAiY29uZCIpCmFMUkwuZGVsdGFfcF9nZW5vIDwtIGFMUkwuZGVsdGFfcF9nZW5vICsgcnJlbW92ZSgibGVnZW5kIikgKyBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kPSJ0LnRlc3QiLCByZWYuZ3JvdXAgPSAiLmFsbC4iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJwLnNpZ25pZiIsIGhpZGUubnMgPSBUKQphTFJMLmRlbHRhX3BfZ2VubwpgYGAKCm9rIC0gYnV0IHRoZXNlIHRyZW5kcyBhcmUgdmVyeSBnZW5lcmFsIC0gbGV0J3MgaGF2ZSBhIGxvb2sgd2hhdCBpcyB0aGUgZGl2ZXJzaXR5IGJldHdlZW4gYWNjZXNzaW9ucyBpbiB0aGVpciBzYWx0IHJlc3BvbnNlcy4gCgojIyBzdHJlc3MtaW5kdWNlZCBjaGFuZ2VzIGluIGdyb3d0aCByYXRlczoKCkFsc28gLSBtYXliZSBsZXRzIGNhbGN1bGF0ZSB0aGUgYXZlcmFnZSBncm93dGggcmF0ZSBwZXIgYWNjZXNzaW9uIGFuZCBsb29rIGhvdyB0aGlzIGxvb2tzIG9uIGEgZ3JhcGggd2l0aCBzb21lIHN0YXRzIC0gYXMgaW4gLSBkbyB3ZSBzZWUgc2lnLiBkaWZmZXJlbmNlcyBiZXR3ZWVuIEMgYW5kIFM6CgpgYGB7cn0KaGVhZChncm93dGhfZmFjdG9ycykKZ3Jvd3RoX25vbmEgPC0gbmEub21pdChncm93dGhfZmFjdG9ycykKc3VtX2dyb3d0aCA8LSBzdW1tYXJ5QnkoZGF0YSA9IGdyb3d0aF9mYWN0b3JzLCBNUi5kZWx0YSArIExSbm8uZGVsdGEgKyBhTFJMLmRlbHRhIH4gY29uZCArIGdlbm90eXBlKQpzdW1fZ3Jvd3RoCgpNUi5kZWx0YV9kb3RwbG90IDwtIGdnZXJyb3JwbG90KHN1bV9ncm93dGgsIHkgPSAiTVIuZGVsdGEubWVhbiIsIHggPSAiY29uZCIsIGZpbGw9ImNvbmQiLCBjb2xvcj0iY29uZCIsIAogICAgICAgICAgICAgICAgICAgICAgICBkZXNjX3N0YXQgPSAibWVhbl9zZCIsIGFkZCA9ICJqaXR0ZXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgYWRkLnBhcmFtcyA9IGxpc3QoY29sb3IgPSAiZGFya2dyYXkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgeGxhYj0iQ29uZGl0aW9uIiwgeWxhYj0iTWFpbiBSb290IEdyb3d0aCAoY20gLyBkYXkpIikgCk1SLmRlbHRhX2RvdHBsb3QgPC0gTVIuZGVsdGFfZG90cGxvdCArIHJyZW1vdmUoImxlZ2VuZCIpICsgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZD0idC50ZXN0IiwgcmVmLmdyb3VwID0gIkMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJwLnNpZ25pZiIsIGhpZGUubnMgPSBUKQpNUi5kZWx0YV9kb3RwbG90CmBgYAoKCmBgYHtyfQphTFJMLmRlbHRhX2RvdHBsb3QgPC0gZ2dlcnJvcnBsb3Qoc3VtX2dyb3d0aCwgeSA9ICJhTFJMLmRlbHRhLm1lYW4iLCB4ID0gImNvbmQiLCBmaWxsPSJjb25kIiwgY29sb3I9ImNvbmQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGVzY19zdGF0ID0gIm1lYW5fc2QiLCBhZGQgPSAiaml0dGVyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGFkZC5wYXJhbXMgPSBsaXN0KGNvbG9yID0gImRhcmtncmF5IiksCiAgICAgICAgICAgICAgICAgICAgICAgIHhsYWI9IkNvbmRpdGlvbiIsIHlsYWI9ImF2ZXJhZ2UgTGF0ZXJhbCBSb290IEdyb3d0aCAoY20gLyBkYXkpIikgCmFMUkwuZGVsdGFfZG90cGxvdCA8LSBhTFJMLmRlbHRhX2RvdHBsb3QgKyBycmVtb3ZlKCJsZWdlbmQiKSArIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2Q9InQudGVzdCIsIHJlZi5ncm91cCA9ICJDIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAicC5zaWduaWYiLCBoaWRlLm5zID0gVCkKYUxSTC5kZWx0YV9kb3RwbG90CmBgYAoKYGBge3J9CkxSbm8uZGVsdGFfZG90cGxvdCA8LSBnZ2Vycm9ycGxvdChzdW1fZ3Jvd3RoLCB5ID0gIkxSbm8uZGVsdGEubWVhbiIsIHggPSAiY29uZCIsIGZpbGw9ImNvbmQiLCBjb2xvcj0iY29uZCIsIAogICAgICAgICAgICAgICAgICAgICAgICBkZXNjX3N0YXQgPSAibWVhbl9zZCIsIGFkZCA9ICJqaXR0ZXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgYWRkLnBhcmFtcyA9IGxpc3QoY29sb3IgPSAiZGFya2dyYXkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgeGxhYj0iQ29uZGl0aW9uIiwgeWxhYj0iYXZlcmFnZSBMYXRlcmFsIFJvb3QgR3Jvd3RoIChjbSAvIGRheSkiKSAKTFJuby5kZWx0YV9kb3RwbG90IDwtIExSbm8uZGVsdGFfZG90cGxvdCArIHJyZW1vdmUoImxlZ2VuZCIpICsgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZD0idC50ZXN0IiwgcmVmLmdyb3VwID0gIkMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJwLnNpZ25pZiIsIGhpZGUubnMgPSBUKQpMUm5vLmRlbHRhX2RvdHBsb3QKYGBgCgpvayAtIG5vdyB3ZSBoYXZlIGFsbCB0aGUgYWNjZXNzaW9uIHZhbHVlcyBhdmVyYWdlZCAtIGxldCdzIGNvbXBhcmUgdGhlIGdyb3d0aCByYXRlIHVuZGVyIGNvbnRyb2wgYW5kIHNhbHQgc3RyZXNzCgpGaXJzdCAtIHdlIG5lZWQgdG8gc3BsaXQgdGhlIGRhdGEgaW50byBjb250cm9sIGFuZCBzYWx0IGFuZCB0aGVuIG1hdGNoIHRoZW0gYmFzZWQgb24gZ2Vub3R5cGU6CgpgYGB7cn0KZ3Jvd3RoX0MgPC0gc3Vic2V0KHN1bV9ncm93dGgsIHN1bV9ncm93dGgkY29uZCA9PSAiQyIpCmdyb3d0aF9TIDwtIHN1YnNldChzdW1fZ3Jvd3RoLCBzdW1fZ3Jvd3RoJGNvbmQgPT0gIlMiKQpjb2xuYW1lcyhncm93dGhfQykgPC0gZ3N1YigiLm1lYW4iLCAiLkNvbnRyb2wiLCBjb2xuYW1lcyhncm93dGhfQykpCmNvbG5hbWVzKGdyb3d0aF9TKSA8LSBnc3ViKCIubWVhbiIsICIuU2FsdCIsIGNvbG5hbWVzKGdyb3d0aF9TKSkKCmdyb3d0aF9DMiA8LSBncm93dGhfQ1ssYygyOjUpXQpncm93dGhfUzIgPC0gZ3Jvd3RoX1NbLGMoMjo1KV0KCnN1bV9ncm93dGgyIDwtIG1lcmdlKGdyb3d0aF9DMiwgZ3Jvd3RoX1MyLCBieT0iZ2Vub3R5cGUiKQpzdW1fZ3Jvd3RoMgpgYGAKCmBgYHtyfQpjb3JycGxvdF9NUl9nciA8LSBnZ3NjYXR0ZXIoc3VtX2dyb3d0aDIsIHggPSAiTVIuZGVsdGEuQ29udHJvbCIsIHkgPSAiTVIuZGVsdGEuU2FsdCIsIHNpemUgPSAwLjMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwgYWRkID0gInJlZy5saW5lIiwgY29sb3IgPSAiTFJuby5kZWx0YS5Db250cm9sIikgKyBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIpCmNvcnJwbG90X01SX2dyIDwtIGNvcnJwbG90X01SX2dyICsgZ3JhZGllbnRfY29sb3IoYygiYmx1ZSIsICJncmV5IiwgInJlZCIpKQpjb3JycGxvdF9NUl9ncgpgYGAKCmBgYHtyfQpjb3JycGxvdF9hTFJMX2dyIDwtIGdnc2NhdHRlcihzdW1fZ3Jvd3RoMiwgeCA9ICJhTFJMLmRlbHRhLkNvbnRyb2wiLCB5ID0gImFMUkwuZGVsdGEuU2FsdCIsIHNpemUgPSAwLjMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwgYWRkID0gInJlZy5saW5lIiwgY29sb3IgPSAiYUxSTC5kZWx0YS5Db250cm9sIikgKyBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIpCmNvcnJwbG90X2FMUkxfZ3IgPC0gY29ycnBsb3RfYUxSTF9nciArIGdyYWRpZW50X2NvbG9yKGMoImJsdWUiLCAiZ3JleSIsICJyZWQiKSkKY29ycnBsb3RfYUxSTF9ncgoKCmBgYAoKYGBge3J9CmNvcnJwbG90X0xSbm9fZ3IgPC0gZ2dzY2F0dGVyKHN1bV9ncm93dGgyLCB4ID0gIkxSbm8uZGVsdGEuQ29udHJvbCIsIHkgPSAiTFJuby5kZWx0YS5TYWx0IiwgY29sb3IgPSAiTFJuby5kZWx0YS5Db250cm9sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IDAuMywgcnVnID0gVFJVRSwgYWRkID0gInJlZy5saW5lIikgKyBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIpCmNvcnJwbG90X0xSbm9fZ3IgPC0gY29ycnBsb3RfTFJub19nciArIGdyYWRpZW50X2NvbG9yKGMoImJsdWUiLCAiZ3JleSIsICJyZWQiKSkKY29ycnBsb3RfTFJub19ncgpgYGAKCmhtbW0uLi4gdGhpbmtpbmcgYWJvdXQgdGhlIGRvdHBsb3RzIGZyb20gZWFybGllciBhbmQgdGhleSAqc2hvdWxkKiBhY3R1YWxseSBiZSBhICpwYWlyZWQqIGdyYXBoLCBiZWNhdXNlIHdlIHdhbnQgdG8gc2VlIGhvdyBpbmRpdmlkdWFsIGFjY2Vzc2lvbnMgYXJlIGJlaGF2aW5nLCBhbmQgd2hldGhlciB0aGF0ICpiZWhhdmlvdXIqIGlzIGNvbnNlcnZlZCBhY3Jvc3MgYWNjZXNzaW9uczoKCmBgYHtyfQpNUl9zdW1fZ3Jvd3RoIDwtIHN1bV9ncm93dGgyWyxjKDEsMiw1KV0KTVJfc3VtX21lbHQgPC0gbWVsdChNUl9zdW1fZ3Jvd3RoKQpNUl9zdW1fbWVsdApNUl9zdW1fbWVsdCR2YXJpYWJsZSA8LSBnc3ViKCJNUi5kZWx0YS4iLCAiIiwgTVJfc3VtX21lbHQkdmFyaWFibGUpCmNvbG5hbWVzKE1SX3N1bV9tZWx0KVsyXSA8LSAiY29uZGl0aW9uIgpjb2xuYW1lcyhNUl9zdW1fbWVsdClbM10gPC0gIk1SLmRlbHRhIgoKCk1SX2dyb3d0aF9wYWlyZWQgPC0gZ2dwYWlyZWQoTVJfc3VtX21lbHQsIHggPSAiY29uZGl0aW9uIiwgeSA9ICJNUi5kZWx0YSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJjb25kaXRpb24iLCBsaW5lLmNvbG9yID0gImdyYXkiLCBsaW5lLnNpemUgPSAwLjEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gImpjbyIsIHhsYWIgPSIiLCB5bGFiID0iTWFpbiBSb290IEdyb3d0aCAoY20gLyBkYXkpIikKTVJfZ3Jvd3RoX3BhaXJlZCA8LSBNUl9ncm93dGhfcGFpcmVkICsgc3RhdF9jb21wYXJlX21lYW5zKHBhaXJlZCA9IFRSVUUsIGxhYmVsLnggPSAxLjUpICsgcnJlbW92ZSgibGVnZW5kIikKTVJfZ3Jvd3RoX3BhaXJlZApgYGAKCkNvb2wgLSB0aGF0IGxvb2tzIG11Y2ggbW9yZSBpbmZvcm1hdGl2ZSAtIGxldCdzIGRvIHRoaXMgZm9yIG90aGVyIHRyYWl0czoKCmBgYHtyfQpMUm5vX3N1bV9ncm93dGggPC0gc3VtX2dyb3d0aDJbLGMoMSwzLDYpXQpMUm5vX3N1bV9ncm93dGggPC0gbmEub21pdChMUm5vX3N1bV9ncm93dGgpCkxSbm9fc3VtX21lbHQgPC0gbWVsdChMUm5vX3N1bV9ncm93dGgpCkxSbm9fc3VtX21lbHQKTFJub19zdW1fbWVsdCR2YXJpYWJsZSA8LSBnc3ViKCJMUm5vLmRlbHRhLiIsICIiLCBMUm5vX3N1bV9tZWx0JHZhcmlhYmxlKQpjb2xuYW1lcyhMUm5vX3N1bV9tZWx0KVsyXSA8LSAiY29uZGl0aW9uIgpjb2xuYW1lcyhMUm5vX3N1bV9tZWx0KVszXSA8LSAiTFJuby5kZWx0YSIKCgpMUm5vX2dyb3d0aF9wYWlyZWQgPC0gZ2dwYWlyZWQoTFJub19zdW1fbWVsdCwgeCA9ICJjb25kaXRpb24iLCB5ID0gIkxSbm8uZGVsdGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiY29uZGl0aW9uIiwgbGluZS5jb2xvciA9ICJncmF5IiwgbGluZS5zaXplID0gMC4xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9ICJqY28iLCB4bGFiID0iIiwgeWxhYiA9IkluY3JlYXNlIGluIExhdGVyYWwgUm9vdCAjICgjIExSIC8gZGF5KSIpCkxSbm9fZ3Jvd3RoX3BhaXJlZCA8LSBMUm5vX2dyb3d0aF9wYWlyZWQgKyBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gVFJVRSwgbGFiZWwueCA9IDEuNSkgKyBycmVtb3ZlKCJsZWdlbmQiKQpMUm5vX2dyb3d0aF9wYWlyZWQKYGBgCgpgYGB7cn0KYUxSTF9zdW1fZ3Jvd3RoIDwtIHN1bV9ncm93dGgyWyxjKDEsNCw3KV0KYUxSTF9zdW1fZ3Jvd3RoIDwtIG5hLm9taXQoYUxSTF9zdW1fZ3Jvd3RoKQphTFJMX3N1bV9tZWx0IDwtIG1lbHQoYUxSTF9zdW1fZ3Jvd3RoKQphTFJMX3N1bV9tZWx0CmFMUkxfc3VtX21lbHQkdmFyaWFibGUgPC0gZ3N1YigiYUxSTC5kZWx0YS4iLCAiIiwgYUxSTF9zdW1fbWVsdCR2YXJpYWJsZSkKY29sbmFtZXMoYUxSTF9zdW1fbWVsdClbMl0gPC0gImNvbmRpdGlvbiIKY29sbmFtZXMoYUxSTF9zdW1fbWVsdClbM10gPC0gImFMUkwuZGVsdGEiCgoKYUxSTF9ncm93dGhfcGFpcmVkIDwtIGdncGFpcmVkKGFMUkxfc3VtX21lbHQsIHggPSAiY29uZGl0aW9uIiwgeSA9ICJhTFJMLmRlbHRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImNvbmRpdGlvbiIsIGxpbmUuY29sb3IgPSAiZ3JheSIsIGxpbmUuc2l6ZSA9IDAuMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSAiamNvIiwgeGxhYiA9IiIsIHlsYWIgPSJhdmVyYWdlIExhdGVyYWwgUm9vdCBHcm93dGggKGNtIC8gZGF5KSIpCmFMUkxfZ3Jvd3RoX3BhaXJlZCA8LSBhTFJMX2dyb3d0aF9wYWlyZWQgKyBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gVFJVRSwgbGFiZWwueCA9IDEuNSkgKyBycmVtb3ZlKCJsZWdlbmQiKQphTFJMX2dyb3d0aF9wYWlyZWQKYGBgCgpvayAtIG5vdyBsZXQncyBzdGFydCBjb21wYXJpbmcgaG93IGluZGl2aWR1YWwgYWNjZXNzaW9ucyBhcmUgZG9pbmcgd2hlbiBpdCBjb21lcyB0byBzYWx0IGluZGljZXMgb2YgaW5kaXZpZHVhbCBvcmdhbnM6CgojIyBTYWx0IFRvbGVyYW5jZSBJbmRleGVzCgpJbiBvcmRlciB0byBsb29rIGF0IHNhbHQgcmVzcG9uc2VzIC0gd2UgbmVlZCB0byBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2UgcGxhbnQgcmVzcG9uc2VzIHBlciBhY2Nlc3Npb24gYW5kIGNhbGN1bGF0ZSB0aGUgcmVsYXRpdmUgY2hhbmdlIGluIGdyb3d0aCByYXRlIGluIHJlc3BvbnNlIHRvIHNhbHQgKHJlbGF0aXZlIHRvIGNvbnRyb2wpOgoKYGBge3J9CmhlYWQoc3VtX2dyb3d0aDIpCgpzdW1fZ3Jvd3RoMiRNUi5TVEkgPC0gc3VtX2dyb3d0aDIkTVIuZGVsdGEuU2FsdC9zdW1fZ3Jvd3RoMiRNUi5kZWx0YS5Db250cm9sCnN1bV9ncm93dGgyJExSbm8uU1RJIDwtIHN1bV9ncm93dGgyJExSbm8uZGVsdGEuU2FsdC9zdW1fZ3Jvd3RoMiRMUm5vLmRlbHRhLkNvbnRyb2wKc3VtX2dyb3d0aDIkYUxSTC5TVEkgPC0gc3VtX2dyb3d0aDIkYUxSTC5kZWx0YS5TYWx0L3N1bV9ncm93dGgyJGFMUkwuZGVsdGEuQ29udHJvbApoZWFkKHN1bV9ncm93dGgyKQpgYGAKClRoZW4gLSB3ZSB3b3VsZCBsaWtlIHRvIGtub3cgYWxzbyB3aGF0IGlzIHRoZSBlZmZlY3Qgb2YgdGhlIHNhbHQgb24gZGlmZmVyZW50IHJvb3QgY29tcG9uZW50cyBhY3Jvc3MgZGlmZmVyZW50IGFjY2Vzc2lvbnMgLSBzbyBsZXQncyBtYWtlIGEgaGlzdG9ncmFtIGZvciB0aGlzIDopCgpgYGB7cn0KY29sbmFtZXMoc3VtX2dyb3d0aDIpClNUSV9oaXN0b19zZXQgPC0gc3VtX2dyb3d0aDJbLGMoMSw4OjEwKV0KaGVhZChTVElfaGlzdG9fc2V0KQpTVElfaGlzdG9fbWVsdCA8LSBtZWx0KFNUSV9oaXN0b19zZXQpCmhlYWQoU1RJX2hpc3RvX21lbHQpCgpTVElfZ3Jvd3RoX2hpc3RvIDwtIGdnaGlzdG9ncmFtKFNUSV9oaXN0b19tZWx0LCB4ID0gInZhbHVlIiwKICAgICAgICAgICAgYWRkID0gIm1lYW4iLCBydWcgPSBUUlVFLAogICAgICAgICAgICBjb2xvciA9ICJ2YXJpYWJsZSIsIGZpbGwgPSAidmFyaWFibGUiLCAKICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMxYjllNzciLCAiI2Q5NWYwMiIsICIjNzU3MGIzIikpICsgeGxhYigiZnJhY3Rpb24gb2YgZ3Jvd3RoIGF0IGNvbnRyb2wiKQpTVElfZ3Jvd3RoX2hpc3RvCmBgYAoKY29vbCAtIG5vdyB3ZSBjYW4gYWxzbyBsb29rIGluIGRldGFpbCBvZiBob3cgdGhlIGluZGl2aWR1YWwgYWNjZXNzaW9ucyBiZWhhdmUgdGhyb3VnaG91dCB0aGVzZSB0aHJlZSBTVEkKCmBgYHtyfQpTVElfZ3Jvd3RoX3BhaXJlZCA8LSBnZ3BhaXJlZChTVElfaGlzdG9fbWVsdCwgeCA9ICJ2YXJpYWJsZSIsIHkgPSAidmFsdWUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAidmFyaWFibGUiLCBsaW5lLmNvbG9yID0gImdyYXkiLCBsaW5lLnNpemUgPSAwLjEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYWxldHRlID0gImpjbyIsIHhsYWIgPSIiLCB5bGFiID0iRnJhY3Rpb24gb2YgcmF0ZSBhdCBDb250cm9sIikKU1RJX2dyb3d0aF9wYWlyZWQgPC0gU1RJX2dyb3d0aF9wYWlyZWQgKyBzdGF0X2NvbXBhcmVfbWVhbnMocGFpcmVkID0gVFJVRSwgbGFiZWwueCA9IDEuNSkgKyBycmVtb3ZlKCJsZWdlbmQiKQpTVElfZ3Jvd3RoX3BhaXJlZApgYGAKCm9rIC0gYWxzbyAtIGxldHMgbG9vayBhdCB0aGVzZSB0aGluZ3MgaW4gYSBiaXQgbW9yZSB0cmFkaXRpb25hbCBzZXR0aW5nOgoKYGBge3J9CnN1bV9ncm93dGgyClNUSV9NUl92c19hTFJMIDwtIGdnc2NhdHRlcihzdW1fZ3Jvd3RoMiwgeCA9ICJNUi5TVEkiLCB5ID0gImFMUkwuU1RJIiwgY29sb3IgPSAiYUxSTC5kZWx0YS5Db250cm9sIiwgc2l6ZSA9IDAuMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWcgPSBUUlVFLCBhZGQgPSAicmVnLmxpbmUiKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikKU1RJX01SX3ZzX2FMUkwgPC0gU1RJX01SX3ZzX2FMUkwgKyBncmFkaWVudF9jb2xvcihjKCJibHVlIiwgImdyZXkiLCAicmVkIikpCgpTVElfTVJfdnNfYUxSTApgYGAKCmBgYHtyfQpTVElfTVJfdnNfTFJubyA8LSBnZ3NjYXR0ZXIoc3VtX2dyb3d0aDIsIHggPSAiTVIuU1RJIiwgeSA9ICJMUm5vLlNUSSIsIGNvbG9yID0gIkxSbm8uZGVsdGEuQ29udHJvbCIsIHNpemUgPSAwLjMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwgYWRkID0gInJlZy5saW5lIikgKyBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIpClNUSV9NUl92c19MUm5vIDwtIFNUSV9NUl92c19MUm5vICsgZ3JhZGllbnRfY29sb3IoYygiYmx1ZSIsICJncmV5IiwgInJlZCIpKQoKU1RJX01SX3ZzX0xSbm8KYGBgCgpgYGB7cn0KU1RJX2FMUkxfdnNfTFJubyA8LSBnZ3NjYXR0ZXIoc3VtX2dyb3d0aDIsIHggPSAiYUxSTC5TVEkiLCB5ID0gIkxSbm8uU1RJIiwgY29sb3IgPSAiTFJuby5kZWx0YS5Db250cm9sIiwgc2l6ZSA9IDAuMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWcgPSBUUlVFLCBhZGQgPSAicmVnLmxpbmUiKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikKU1RJX2FMUkxfdnNfTFJubyA8LSBTVElfYUxSTF92c19MUm5vICsgZ3JhZGllbnRfY29sb3IoYygiYmx1ZSIsICJncmV5IiwgInJlZCIpKQoKU1RJX2FMUkxfdnNfTFJubwpgYGAKCiMjIENvbmNsdXNpb25zIHNvIGZhcgoKT0sgLSBzbyBhbGwgb2YgdGhlIGFib3ZlIGlzIHByZXR0eSBpbnRlcmVzdGluZyAtIGZyb20gdGhlIHBhaXJlZCBTVEkgZ3JhcGggd2UgY2FuIHRlbGwgdGhhdCB0aGVyZSBhcmUgbXVsdGlwbGUgY2xhc3NlcyBvZiBhY2Nlc3Npb25zOgoKYGBge3J9ClNUSV9ncm93dGhfcGFpcmVkCmBgYAoKMSkgYWNjZXNzaW9ucyB0aGF0IGFyZSBlcXVhbGx5IGltcGFpcmVkIGZvciBhbGwgY29tcG9uZW50cyBvZiBSU0EKMikgYWNjZXNzaW9ucyB0aGF0IGFyZSBMRUFTVCBpbXBhaXJlZCBpbiBNUkwKMykgYWNjZXNzaW9ucyB0aGF0IGFyZSBNT1NUIGltcGFpcmVkIGluIE1STAo0KSBhY2Nlc3Npb25zIHRoYXQgYXJlIE1PU1QgaW1wYWlyZWQgaW4gTFJubwoKVGhlIGNvcnJlbGF0aW9ucyBiZXR3ZWVuIGluZGl2aWR1YWwgU0lUcyBpcyB2ZXJ5IGxvdyBmb3IgYWxsIGNvbWJpbmF0aW9ucyAtIHdoaWNoIGlzIHByZXR0eSBleGNpdGluZywgYW5kIGFMUkwgYW5kIE1STCBhcmUgaW4gZ2VuZXJhbCB0aGUgbGVhc3QgaW1wYWN0ZWQgYnkgdGhlIHNhbHQgc3RyZXNzIC0gd2hpbGUgTFJubyBpcyBpbXBhaXJlZCBpbiBtb3N0IGFjY2Vzc2lvbnMgdGhlIG1vc3QgLSBiYXNlZCBvbiB0aGlzIGhpc3RvZ3JhbToKCmBgYHtyfQpTVElfZ3Jvd3RoX2hpc3RvCmBgYAoKbm93IC0gSSBhbSB3b25kZXJpbmcgLSBpZiB3ZSB0aHJvdyBvbmx5IHRoZSBTVEkgaW50byB0aGUgaGllcmFyY2hpY2FsIGNsdXN0ZXJpbmcgLSB3b3VsZCB3ZSBiZSBhYmxlIHRvIGRpc2Nlcm4gYmV0d2VlbiB0aGVzZSBjbGFzc2VzIG9mIGFjY2Vzc2lvbnM/CgpMZXQncyBzZWU6CgojIyBIY2x1c3QgYmFzZWQgb24gdGhlIFNJVHM6CgpGaXJzdCAtIGxldCdzIHByZXBhcmUgdGhlIG1hdHJpeDoKCmBgYHtyfQpjb2xuYW1lcyhzdW1fZ3Jvd3RoMikKU1RJX29ubHkgPC0gc3VtX2dyb3d0aDJbLGMoMSw4OjEwKV0KIyBnZXQgb25seSBudW1lcmljIHZhcmlhYmxlcyBmcm9tIHlvdXIgZGF0YSAtIE5PVCBwbGFudCBpZGVudGlmaWVycyAKU1RJX21hdHJpeCA8LSBTVElfb25seVssIGMoMjo0KV0KIyB0cmFuc2ZlciBhbGwgbnVtZXJpYyB2YXJpYWJsZXMgaW50byBtYXRyaXgKU1RJX21hdHJpeDIgPC0gYXMubWF0cml4KFNUSV9tYXRyaXgpCiMgYWRkIHBsYW50IGlkZW50aWZpZXJzIGFzIHJvdyBuYW1lcwpyb3cubmFtZXMoU1RJX21hdHJpeDIpIDwtIFNUSV9vbmx5JGdlbm90eXBlCiMgb21pdCBtaXNzaW5nIHZhbHVlcyAtIG90aGVyd2lzZSB3ZSB3b250IGJlIGFibGUgdG8gZG8gdGhlIGNsdXN0ZXJpbmcgCmZpbmFsX20gPC0gbmEub21pdChTVElfbWF0cml4MikKZGltKFNUSV9tYXRyaXgyKQpkaW0oZmluYWxfbSkKaGVhZChmaW5hbF9tKQpgYGAKCmBgYHtyfQojIHJ1biBhIGNvcnJlbGF0aW9uCm1hZ2RhX2NvciA9IGNvcihmaW5hbF9tLG1ldGhvZD1jKCJwZWFyc29uIikpCiMgY2FsY3VsYXRlIGRpc3RhbmNlCm1hZ2RhX2Rpc3QgPSBkaXN0KG1hZ2RhX2NvcikKIyB0aGlzIGlzIHRoZSBjbHVzdGVyaW5nIGl0c2VsZiAtIGJ1dCBub3cgd2UgYXJlIGNsdXN0ZXJpbmcgaG93IHBoZW5vdHlwZXMgYXJlIHJlbGF0ZWQgdG8gZWFjaG90aGVyCm1hZ2RhX2NsdXN0ID0gaGNsdXN0KG1hZ2RhX2Rpc3QsbWV0aG9kPSJ3YXJkLkQyIikKcGxvdChhcy5kZW5kcm9ncmFtKG1hZ2RhX2NsdXN0KSxob3Jpej1UKQojIHRyYW5zcG9zaW5nIHRoZSBtYXRyaXgKbWFnZGFfdF9tYXRyaXg9dChmaW5hbF9tKQptYWdkYV90X2NvciA9IGNvcihtYWdkYV90X21hdHJpeCxtZXRob2Q9YygicGVhcnNvbiIpKQptYWdkYV90X2Rpc3QgPSBkaXN0KG1hZ2RhX3RfY29yKQojIGNsdXN0ZXJpbmcgb2YgYWNjZXNzaW9ucwptYWdkYV90X2NsdXN0ID0gaGNsdXN0KG1hZ2RhX3RfZGlzdCxtZXRob2Q9IndhcmQuRDIiKQpwbG90KGFzLmRlbmRyb2dyYW0obWFnZGFfdF9jbHVzdCksaG9yaXo9VCkKY2x1c3RlcnMgPC0gY3V0cmVlKG1hZ2RhX3RfY2x1c3QsaD0yNCkKdW5pcXVlKGNsdXN0ZXJzKQp3cml0ZS50YWJsZShhcy5kYXRhLmZyYW1lKGN1dHJlZShtYWdkYV90X2NsdXN0LGg9MjQpKSxmaWxlPSJTVElfY2x1c3RlcnMudHh0IixzZXA9Ilx0IixxdW90ZT1GKQojIHRoZSBzY2FsaW5nIG9ubHkgbm93IGFwcGxpZXMgdG8gInJvdyIgd2hpY2ggYXJlIG91ciBkaWZmZXJlbnQgcGhlbm90eXBlcwpoZWF0bWFwLjIobWFnZGFfdF9tYXRyaXgsUm93dj1hcy5kZW5kcm9ncmFtKG1hZ2RhX2NsdXN0KSxDb2x2PWFzLmRlbmRyb2dyYW0obWFnZGFfdF9jbHVzdCksY29sPWJsdWUycmVkKDEwMCksc2NhbGU9Yygicm93IiksZGVuc2l0eS5pbmZvPSJub25lIix0cmFjZT0ibm9uZSIpCmBgYAoKT0sgLSBsZXQncyBzYXZlIHRoaXMgb25lIGludG8gYSBmaWxlIGJlZm9yZSB3ZSBmb3JnZXQKCmBgYHtyfQpwZGYoIkZpZy5TVElfY2x1c3RlcmluZy5wZGYiLHdpZHRoPTEyLGhlaWdodD03KQpoZWF0bWFwLjIobWFnZGFfdF9tYXRyaXgsUm93dj1hcy5kZW5kcm9ncmFtKG1hZ2RhX2NsdXN0KSxDb2x2PWFzLmRlbmRyb2dyYW0obWFnZGFfdF9jbHVzdCksY29sPWJsdWUycmVkKDEwMCksc2NhbGU9Yygicm93IiksZGVuc2l0eS5pbmZvPSJub25lIix0cmFjZT0ibm9uZSIpCmRldi5vZmYoKQpgYGAKCmNvb2wgLSBub3cgbGV0J3Mgc2VlIGlmIHRoZSBjbHVzdGVycyBhY3R1YWxseSBkaWZmZXIgaW4gdGhlaXIgcmVzcGVjdGl2ZSBncm93dGggcmF0ZXMgLyBTVElzLgoKRmlyc3QgLSBsZXQncyBmdXNlICJjbHVzdGVycyIgd2l0aCB0aGUgb3RoZXIgZ3Jvd3RoIHJhdGUgZGF0YQpgYGB7cn0KY2x1c3RlcnMKCnN1bWF0cml4IDwtIHN1bV9ncm93dGgyWyxjKDI6MTApXQpzdW1hdHJpeDIgPC0gYXMubWF0cml4KHN1bWF0cml4KQpyb3cubmFtZXMoc3VtYXRyaXgyKSA8LSBzdW1fZ3Jvd3RoMiRnZW5vdHlwZQpzdW1hdHJpeDMgPC0gbmEub21pdChzdW1hdHJpeDIpCgpzdW1fZ3Jvd3RoMyA8LSBjYmluZChzdW1hdHJpeDMsIGNsdXN0ZXJzKQpoZWFkKHN1bV9ncm93dGgzKQpgYGAKCm9rIC0gbm93IGxldCdzIG1ha2Ugc29tZSBncmFwaHMgcGVyIGNsdXN0ZXJzIHN0YXJ0aW5nIHdpdGggU1RJczoKCmBgYHtyfQpncm93dGhfY2x1c3RlcjMgPC0gYXMuZGF0YS5mcmFtZShzdW1fZ3Jvd3RoMykKZ3Jvd3RoX2NsdXN0ZXIzCgpTVEljbHVzdGVyX01SLlNUSSA8LSBnZ2Vycm9ycGxvdChncm93dGhfY2x1c3RlcjMsIHkgPSAiTVIuU1RJIiwgeCA9ICJjbHVzdGVycyIsIGZpbGw9ImNsdXN0ZXJzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9ImNsdXN0ZXJzIiwgZGVzY19zdGF0ID0gIm1lYW5fc2QiLCBhZGQgPSAiaml0dGVyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkLnBhcmFtcyA9IGxpc3QoY29sb3IgPSAiZGFya2dyYXkiKSwgeGxhYj0iIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWxhYj0iRnJhY3Rpb24gb2YgQ29udHJvbCAoTWFpbiBSb290IEdyb3d0aCkiLCB0aXRsZSA9ICJNYWluIFJvb3QgU1RJIikgClNUSWNsdXN0ZXJfTVIuU1RJIDwtIFNUSWNsdXN0ZXJfTVIuU1RJICsgcnJlbW92ZSgibGVnZW5kIikgKyBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kPSJ0LnRlc3QiLCByZWYuZ3JvdXAgPSAxLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJwLnNpZ25pZiIsIGhpZGUubnMgPSBUKQpTVEljbHVzdGVyX01SLlNUSQpgYGAKCmBgYHtyfQpTVEljbHVzdGVyX0xSbm8uU1RJIDwtIGdnZXJyb3JwbG90KGdyb3d0aF9jbHVzdGVyMywgeSA9ICJMUm5vLlNUSSIsIHggPSAiY2x1c3RlcnMiLCBmaWxsPSJjbHVzdGVycyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPSJjbHVzdGVycyIsIGRlc2Nfc3RhdCA9ICJtZWFuX3NkIiwgYWRkID0gImppdHRlciIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZC5wYXJhbXMgPSBsaXN0KGNvbG9yID0gImRhcmtncmF5IiksIHhsYWI9IiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWI9IkZyYWN0aW9uIG9mIENvbnRyb2wgKExSICMpIiwgdGl0bGUgPSAiTGF0ZXJhbCBSb290ICMgU1RJIikgClNUSWNsdXN0ZXJfTFJuby5TVEkgPC0gU1RJY2x1c3Rlcl9MUm5vLlNUSSArIHJyZW1vdmUoImxlZ2VuZCIpICsgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZD0idC50ZXN0IiwgcmVmLmdyb3VwID0gMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAicC5zaWduaWYiLCBoaWRlLm5zID0gVCkKU1RJY2x1c3Rlcl9MUm5vLlNUSQpgYGAKCmBgYHtyfQpTVEljbHVzdGVyX2FMUkwuU1RJIDwtIGdnZXJyb3JwbG90KGdyb3d0aF9jbHVzdGVyMywgeSA9ICJhTFJMLlNUSSIsIHggPSAiY2x1c3RlcnMiLCBmaWxsPSJjbHVzdGVycyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPSJjbHVzdGVycyIsIGRlc2Nfc3RhdCA9ICJtZWFuX3NkIiwgYWRkID0gImppdHRlciIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZC5wYXJhbXMgPSBsaXN0KGNvbG9yID0gImRhcmtncmF5IiksIHhsYWI9IiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWI9IkZyYWN0aW9uIG9mIENvbnRyb2wgKGF2Zy4gTGF0ZXJhbCBSb290IEdyb3d0aCkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICIgYXZnIExhdGVyYWwgUm9vdCBHcm93dGggU1RJIikgClNUSWNsdXN0ZXJfYUxSTC5TVEkgPC0gU1RJY2x1c3Rlcl9hTFJMLlNUSSArIHJyZW1vdmUoImxlZ2VuZCIpICsgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZD0idC50ZXN0IiwgcmVmLmdyb3VwID0gMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAicC5zaWduaWYiLCBoaWRlLm5zID0gVCkKU1RJY2x1c3Rlcl9hTFJMLlNUSQpgYGAKCkxldCdzIHB1dCB0aGVzZSBpbnRvIG9uZSBmaWd1cmUgYW5kIHRoaW5rIGFib3V0IGl0IGluIGFub3RoZXIgc2Vzc2lvbjoKCmBgYHtyfQpwZGYoIkZpZy5TVElfYmFzZWRfY2x1c3RlcnNfU1RJX3RyYWl0X2NvbXBhcmlzb24ucGRmIiwgaGVpZ2h0ID0gMTUsIHdpZHRoID0gMTApCnBsb3RfZ3JpZChTVEljbHVzdGVyX01SLlNUSSwgU1RJY2x1c3Rlcl9MUm5vLlNUSSwgU1RJY2x1c3Rlcl9hTFJMLlNUSSwgbmNvbD0xLCBsYWJlbHM9IkFVVE8iKQpkZXYub2ZmKCkKYGBgCgpJIG0gc3RpbGwgd29uZGVyaW5nIGhvdyB0aGUgY29ycmVsYXRpb25zIGJldHdlZW4gdGhlIHRyYWl0cyB3b3VsZCBsb29rIGlmIHdlIHdvdWxkIGNvbG9yIGl0IHBlciBjbHVzdGVyIG5vdzoKCmBgYHtyfQpncm93dGhfY2x1c3RlcjMkY2x1c3RlcnMgPC0gYXMuZmFjdG9yKGdyb3d0aF9jbHVzdGVyMyRjbHVzdGVycykKClNUSV9hTFJMX3ZzX0xSbm9fY2x1c3QgPC0gZ2dzY2F0dGVyKGdyb3d0aF9jbHVzdGVyMywgeCA9ICJhTFJMLlNUSSIsIHkgPSAiTFJuby5TVEkiLCBjb2xvciA9ICJjbHVzdGVycyIsIHNpemUgPSAwLjMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwgZWxsaXBzZSA9IFRSVUUsIHBhbGV0dGUgPSAiamNvIikgKyBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIpClNUSV9hTFJMX3ZzX0xSbm9fY2x1c3QKYGBgCgpgYGB7cn0KU1RJX2FMUkxfdnNfTVJfY2x1c3QgPC0gZ2dzY2F0dGVyKGdyb3d0aF9jbHVzdGVyMywgeCA9ICJhTFJMLlNUSSIsIHkgPSAiTVIuU1RJIiwgY29sb3IgPSAiY2x1c3RlcnMiLCBzaXplID0gMC4zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsIGVsbGlwc2UgPSBUUlVFLCBwYWxldHRlID0gImpjbyIpICsgc3RhdF9jb3IobWV0aG9kID0gInBlYXJzb24iKQpTVElfYUxSTF92c19NUl9jbHVzdApgYGAKCmBgYHtyfQpTVElfTFJub192c19NUl9jbHVzdCA8LSBnZ3NjYXR0ZXIoZ3Jvd3RoX2NsdXN0ZXIzLCB4ID0gIkxSbm8uU1RJIiwgeSA9ICJNUi5TVEkiLCBjb2xvciA9ICJjbHVzdGVycyIsIHNpemUgPSAwLjMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwgZWxsaXBzZSA9IFRSVUUsIHBhbGV0dGUgPSAiamNvIikgKyBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIpClNUSV9MUm5vX3ZzX01SX2NsdXN0CmBgYAoKSSB3b25kZXIgaWYgd2UgY291bGQgdmlzdWFsaXplIGFjY2Vzc2lvbnMgdGhhdCBiZWxvbmcgdG8gaW5kaXZpZHVhbCBjbHVzdGVycyBpbiB0aGUgY29udGludW91cyBncmFwaHMgd2l0aCBhdmVyYWdlIHBlciBhY2Nlc3Npb24uCgpMZXQncyBsb2FkIHRoZSBTVElfY2x1c3RlciB0YWJsZToKYGBge3J9CmNsdXN0ZXIwMSA8LSByZWFkLnRhYmxlKCJTVElfY2x1c3RlcnNfYmV0dGVyLnR4dCIsIGhlYWRlciA9IFQpCmhlYWQoY2x1c3RlcjAxKQpgYGAKCm5vdyBsZXQncyBmdXNlIGl0IHdpdGggdGhlIE1SX3N1bSBkYXRhc2V0IHRoYXQgd2UgdXNlZCBwcmV2aW91c2x5IGZvciB0aW1lc2VyaWVzIGdyYXBoczoKCmBgYHtyfQpoZWFkKE1SX3N1bSkKTVJfc3VtMiA8LSBNUl9zdW0KTVJfc3VtMiRnZW5vdHlwZSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihNUl9zdW0yJGdlbm90eXBlKSkKTVJfY2x1c3RlciA8LSBtZXJnZShNUl9zdW0yLCBjbHVzdGVyMDEsIGJ5PSJnZW5vdHlwZSIsIGFsbD1UKQpoZWFkKE1SX2NsdXN0ZXIpCk1SX2NsdXN0ZXIkY2x1c3RlciA8LSBhcy5mYWN0b3IoTVJfY2x1c3RlciRjbHVzdGVyKQpgYGAKCkNvb2wgLSBub3cgbGV0J3Mgc2VlIGhvdyB0aGUgVFJTIGdyYXBoIGxvb2tzIGxpa2Ugd2hlbiB3ZSBjb2xvdXIgcGVyIGNsdXN0ZXI6CgpgYGB7cn0KVFJTX2NsdXN0X2xncmFwaCA8LSBnZ3Bsb3QoZGF0YT1NUl9jbHVzdGVyLCBhZXMoeD0gREFTLCB5PVRSUy5tZWFuLCBncm91cCA9IGdlbm9fY29uZCwgY29sb3IgPSBjb25kKSkgClRSU19jbHVzdF9sZ3JhcGggPC0gVFJTX2NsdXN0X2xncmFwaCArIGdlb21fbGluZShhbHBoYSA9IDAuMSkgClRSU19jbHVzdF9sZ3JhcGggPC0gVFJTX2NsdXN0X2xncmFwaCArIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IG1lYW5fc2UsIGdlb209InJpYmJvbiIsIGxpbmV0eXBlPTAsIGFlcyhncm91cD1jb25kKSwgYWxwaGE9MC4zKSArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpUUlNfY2x1c3RfbGdyYXBoIDwtIFRSU19jbHVzdF9sZ3JhcGggKyBnZ3RpdGxlKCIiKSArZmFjZXRfZ3JpZCh+IGNsdXN0ZXIpClRSU19jbHVzdF9sZ3JhcGggPC0gVFJTX2NsdXN0X2xncmFwaCArIHlsYWIoIlRvdGFsIFJvb3QgU2l6ZSAoY20pIikgKyB4bGFiKCJEYXlzIEFmdGVyIFN0cmVzcyIpClRSU19jbHVzdF9sZ3JhcGgKYGBgCgoKCmBgYHtyfQpTVEljbHVzdGVyX01SLkMgPC0gZ2dlcnJvcnBsb3QoZ3Jvd3RoX2NsdXN0ZXIzLCB5ID0gIk1SLmRlbHRhLkNvbnRyb2wiLCB4ID0gImNsdXN0ZXJzIiwgZmlsbD0iY2x1c3RlcnMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj0iY2x1c3RlcnMiLCBkZXNjX3N0YXQgPSAibWVhbl9zZCIsIGFkZCA9ICJqaXR0ZXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGQucGFyYW1zID0gbGlzdChjb2xvciA9ICJkYXJrZ3JheSIpLCB4bGFiPSJDbHVzdGVycyBiYXNlZCBvbiBTVEkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiPSJNYWluIFJvb3QgR3Jvd3RoIChjbSAvIGRheSkiLCB0aXRsZSA9ICJDb250cm9sIikgClNUSWNsdXN0ZXJfTVIuQyA8LSBTVEljbHVzdGVyX01SLkMgKyBycmVtb3ZlKCJsZWdlbmQiKSArIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2Q9InQudGVzdCIsIHJlZi5ncm91cCA9IDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gInAuc2lnbmlmIiwgaGlkZS5ucyA9IFQpClNUSWNsdXN0ZXJfTVIuQwpgYGAKCmBgYHtyfQpTVEljbHVzdGVyX01SLlMgPC0gZ2dlcnJvcnBsb3QoZ3Jvd3RoX2NsdXN0ZXIzLCB5ID0gIk1SLmRlbHRhLlNhbHQiLCB4ID0gImNsdXN0ZXJzIiwgZmlsbD0iY2x1c3RlcnMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj0iY2x1c3RlcnMiLCBkZXNjX3N0YXQgPSAibWVhbl9zZCIsIGFkZCA9ICJqaXR0ZXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGQucGFyYW1zID0gbGlzdChjb2xvciA9ICJkYXJrZ3JheSIpLCB4bGFiPSJDbHVzdGVycyBiYXNlZCBvbiBTVEkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiPSJNYWluIFJvb3QgR3Jvd3RoIChjbSAvIGRheSkiLCB0aXRsZSA9ICJTYWx0IikgClNUSWNsdXN0ZXJfTVIuUyA8LSBTVEljbHVzdGVyX01SLlMgKyBycmVtb3ZlKCJsZWdlbmQiKSArIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2Q9InQudGVzdCIsIHJlZi5ncm91cCA9IDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gInAuc2lnbmlmIiwgaGlkZS5ucyA9IFQpClNUSWNsdXN0ZXJfTVIuUwpgYGAKCmBgYHtyfQpTVEljbHVzdGVyX2FMUi5DIDwtIGdnZXJyb3JwbG90KGdyb3d0aF9jbHVzdGVyMywgeSA9ICJhTFJMLmRlbHRhLkNvbnRyb2wiLCB4ID0gImNsdXN0ZXJzIiwgZmlsbD0iY2x1c3RlcnMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj0iY2x1c3RlcnMiLCBkZXNjX3N0YXQgPSAibWVhbl9zZCIsIGFkZCA9ICJqaXR0ZXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGQucGFyYW1zID0gbGlzdChjb2xvciA9ICJkYXJrZ3JheSIpLCB4bGFiPSJDbHVzdGVycyBiYXNlZCBvbiBTVEkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiPSJhdmcgTGF0ZXJhbCBSb290IEdyb3d0aCAoY20gLyBkYXkpIiwgdGl0bGUgPSAiQ29udHJvbCIpIApTVEljbHVzdGVyX2FMUi5DIDwtIFNUSWNsdXN0ZXJfYUxSLkMgKyBycmVtb3ZlKCJsZWdlbmQiKSArIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2Q9InQudGVzdCIsIHJlZi5ncm91cCA9IDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gInAuc2lnbmlmIiwgaGlkZS5ucyA9IFQpClNUSWNsdXN0ZXJfYUxSLkMKYGBgCgpgYGB7cn0KU1RJY2x1c3Rlcl9hTFIuUyA8LSBnZ2Vycm9ycGxvdChncm93dGhfY2x1c3RlcjMsIHkgPSAiYUxSTC5kZWx0YS5TYWx0IiwgeCA9ICJjbHVzdGVycyIsIGZpbGw9ImNsdXN0ZXJzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9ImNsdXN0ZXJzIiwgZGVzY19zdGF0ID0gIm1lYW5fc2QiLCBhZGQgPSAiaml0dGVyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkLnBhcmFtcyA9IGxpc3QoY29sb3IgPSAiZGFya2dyYXkiKSwgeGxhYj0iQ2x1c3RlcnMgYmFzZWQgb24gU1RJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWxhYj0iYXZnIExhdGVyYWwgUm9vdCBHcm93dGggKGNtIC8gZGF5KSIsIHRpdGxlID0gIlNhbHQiKSAKU1RJY2x1c3Rlcl9hTFIuUyA8LSBTVEljbHVzdGVyX2FMUi5TICsgcnJlbW92ZSgibGVnZW5kIikgKyBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kPSJ0LnRlc3QiLCByZWYuZ3JvdXAgPSAxLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJwLnNpZ25pZiIsIGhpZGUubnMgPSBUKQpTVEljbHVzdGVyX2FMUi5TCmBgYAoKYGBge3J9ClNUSWNsdXN0ZXJfTFJuby5DIDwtIGdnZXJyb3JwbG90KGdyb3d0aF9jbHVzdGVyMywgeSA9ICJMUm5vLmRlbHRhLkNvbnRyb2wiLCB4ID0gImNsdXN0ZXJzIiwgZmlsbD0iY2x1c3RlcnMiICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj0iY2x1c3RlcnMiLCBkZXNjX3N0YXQgPSAibWVhbl9zZCIsIGFkZCA9ICJqaXR0ZXIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGQucGFyYW1zID0gbGlzdChjb2xvciA9ICJkYXJrZ3JheSIpLCB4bGFiPSJDbHVzdGVycyBiYXNlZCBvbiBTVEkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiPSJMYXRlcmFsIFJvb3QgSW5jcmVhc2UgKCMgTFIgLyBkYXkpIiwgdGl0bGUgPSAiQ29udHJvbCIpIApTVEljbHVzdGVyX0xSbm8uQyA8LSBTVEljbHVzdGVyX0xSbm8uQyArIHJyZW1vdmUoImxlZ2VuZCIpICsgc3RhdF9jb21wYXJlX21lYW5zKG1ldGhvZD0idC50ZXN0IiwgcmVmLmdyb3VwID0gMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSAicC5zaWduaWYiLCBoaWRlLm5zID0gVCkKU1RJY2x1c3Rlcl9MUm5vLkMKbGlicmFyeShwbG90bHkpCmdncGxvdGx5KFNUSWNsdXN0ZXJfTFJuby5DKQpgYGAKCgpgYGB7cn0KU1RJY2x1c3Rlcl9MUm5vLlMgPC0gZ2dlcnJvcnBsb3QoZ3Jvd3RoX2NsdXN0ZXIzLCB5ID0gIkxSbm8uZGVsdGEuU2FsdCIsIHggPSAiY2x1c3RlcnMiLCBmaWxsPSJjbHVzdGVycyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPSJjbHVzdGVycyIsIGRlc2Nfc3RhdCA9ICJtZWFuX3NkIiwgYWRkID0gImppdHRlciIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZC5wYXJhbXMgPSBsaXN0KGNvbG9yID0gImRhcmtncmF5IiksIHhsYWI9IkNsdXN0ZXJzIGJhc2VkIG9uIFNUSSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWI9IkxhdGVyYWwgUm9vdCBJbmNyZWFzZSAoIyBMUiAvIGRheSkiLCB0aXRsZSA9ICJTYWx0IikgClNUSWNsdXN0ZXJfTFJuby5TIDwtIFNUSWNsdXN0ZXJfTFJuby5TICsgcnJlbW92ZSgibGVnZW5kIikgKyBzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kPSJ0LnRlc3QiLCByZWYuZ3JvdXAgPSAxLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9ICJwLnNpZ25pZiIsIGhpZGUubnMgPSBUKQpTVEljbHVzdGVyX0xSbm8uUwpgYGAKCmBgYHtyfQpnZ3Bsb3RseShUUlNfbGdyYXBoKQpgYGAKCkxldCdzIGhhdmUgYSBsb29rIGFuZCBzZWxlY3QgYWNjZXNzaW9uczoKCmBgYHtyfQp0b21hdG8gPC0gc3Vic2V0KE1SX3N1bSwgTVJfc3VtJERBUyA+IDMpCnRvbWF0byA8LSBzdWJzZXQodG9tYXRvLCB0b21hdG8kY29uZCA9PSAiUyIpCnRvbWF0byA8LSBzdWJzZXQodG9tYXRvLCB0b21hdG8kVFJTLm1lYW4gPiAxOSkKdG9tYXRvJGdlbm90eXBlCgpgYGAKCnRoYXQncyBvZiBjb3Vyc2UgYmFzZWQgb24gdGhlIG1lYW4gLSBsZXRzIGhhdmUgYSBsb29rIGF0IHRoZSBtb3N0IGludGVyZXN0aW5nIGFjY2Vzc2lvbnMgdGhvOgoKYGBge3J9CmludGVyZXN0aW5nIDwtIHN1YnNldChhbGxfTVIzLCBhbGxfTVIzJGdlbm90eXBlID09ICIgMDAyIikKaW50ZXJlc3RpbmcKCk0wMDJfbGdyYXBoIDwtIGdncGxvdChkYXRhPWludGVyZXN0aW5nLCBhZXMoeD0gREFTLCB5PVRSUywgZ3JvdXAgPSByb290X25hbWUsIGNvbG9yID0gY29uZCkpIApNMDAyX2xncmFwaCA8LSBNMDAyX2xncmFwaCArZ2VvbV9saW5lKGFscGhhID0gMC4xKSAKTTAwMl9sZ3JhcGggPC0gTTAwMl9sZ3JhcGggKyBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NlLCBnZW9tPSJyaWJib24iLCBsaW5ldHlwZT0wLCBhZXMoZ3JvdXA9Y29uZCksIGFscGhhPTAuMykKTTAwMl9sZ3JhcGggPC0gTTAwMl9sZ3JhcGggKyBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgYWVzKGdyb3VwPSBjb25kKSwgIHNpemU9MC43LCBnZW9tPSJsaW5lIiwgbGluZXR5cGUgPSAiZGFzaGVkIikKTTAwMl9sZ3JhcGggPC0gTTAwMl9sZ3JhcGggKyBzdGF0X2NvbXBhcmVfbWVhbnMoYWVzKGdyb3VwID0gY29uZCksIGxhYmVsID0gInAuc2lnbmlmIiwgbWV0aG9kID0gInQudGVzdCIsIGhpZGUubnMgPSBUKQpNMDAyX2xncmFwaCA8LSBNMDAyX2xncmFwaCArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygic3RlZWxibHVlIiwgImZpcmVicmljazMiKSkgKyBnZ3RpdGxlKCJNMDAyIikKTTAwMl9sZ3JhcGggPC0gTTAwMl9sZ3JhcGggKyB5bGFiKCJUb3RhbCBSb290IFNpemUgKGNtKSIpICsgeGxhYigiRGF5cyBBZnRlciBTdHJlc3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScpCk0wMDJfbGdyYXBoCmBgYAoKCmBgYHtyfQppbnRlcmVzdGluZyA8LSBzdWJzZXQoYWxsX01SMywgYWxsX01SMyRnZW5vdHlwZSA9PSAiIDI0OCIpCmludGVyZXN0aW5nCgpNMjQ4X2xncmFwaCA8LSBnZ3Bsb3QoZGF0YT1pbnRlcmVzdGluZywgYWVzKHg9IERBUywgeT1UUlMsIGdyb3VwID0gcm9vdF9uYW1lLCBjb2xvciA9IGNvbmQpKSAKTTI0OF9sZ3JhcGggPC0gTTI0OF9sZ3JhcGggK2dlb21fbGluZShhbHBoYSA9IDAuMSkgCk0yNDhfbGdyYXBoIDwtIE0yNDhfbGdyYXBoICsgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gbWVhbl9zZSwgZ2VvbT0icmliYm9uIiwgbGluZXR5cGU9MCwgYWVzKGdyb3VwPWNvbmQpLCBhbHBoYT0wLjMpCk0yNDhfbGdyYXBoIDwtIE0yNDhfbGdyYXBoICsgc3RhdF9zdW1tYXJ5KGZ1bi55PW1lYW4sIGFlcyhncm91cD0gY29uZCksICBzaXplPTAuNywgZ2VvbT0ibGluZSIsIGxpbmV0eXBlID0gImRhc2hlZCIpCk0yNDhfbGdyYXBoIDwtIE0yNDhfbGdyYXBoICsgc3RhdF9jb21wYXJlX21lYW5zKGFlcyhncm91cCA9IGNvbmQpLCBsYWJlbCA9ICJwLnNpZ25pZiIsIG1ldGhvZCA9ICJ0LnRlc3QiLCBoaWRlLm5zID0gVCkKTTI0OF9sZ3JhcGggPC0gTTI0OF9sZ3JhcGggKyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoInN0ZWVsYmx1ZSIsICJmaXJlYnJpY2szIikpICsgZ2d0aXRsZSgiTTI0OCIpCk0yNDhfbGdyYXBoIDwtIE0yNDhfbGdyYXBoICsgeWxhYigiVG90YWwgUm9vdCBTaXplIChjbSkiKSArIHhsYWIoIkRheXMgQWZ0ZXIgU3RyZXNzIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249J25vbmUnKQpNMjQ4X2xncmFwaApgYGAKCiMjIFBhcmV0byBhbmQgUlNBCgpPSyAtIHNvIG5vdyBsZXQncyBnZXQgdG8gdGhlIGFjdHVhbCBwYXJldGhvIGNhbGN1bGF0aW9ucyBtYWRlIGJ5IEFyanVuLgoKYGBge3J9CmdldHdkKCkKUGFyZXRvXzAxIDwtIHJlYWQuY3N2KCIvVXNlcnMvbWFnZGFsZW5hL0Ryb3Bib3gvRGF0YUFuZEFuYWx5c2lzL1RvbWF0by9QaW1waUJJRyBjc3YgcmF3IGZpbGVzL0FyanVuX1BhcmV0aG8vYXJib3Jfc3RhdHMuY3N2IikKUGFyZXRvXzAxClBhcmV0b18wMiA8LSByZWFkLmNzdigiL1VzZXJzL21hZ2RhbGVuYS9Ecm9wYm94L0RhdGFBbmRBbmFseXNpcy9Ub21hdG8vUGltcGlCSUcgY3N2IHJhdyBmaWxlcy9Bcmp1bl9QYXJldGhvL3NjYWxpbmdfZGlzdGFuY2VzLmNzdiIpClBhcmV0b18wMgpoZWFkKGFsbF9NUjMpCm1ldGEgPC0gcmVhZC5jc3YoIi9Vc2Vycy9tYWdkYWxlbmEvRHJvcGJveC9EYXRhQW5kQW5hbHlzaXMvVG9tYXRvL1BpbXBpQklHIGNzdiByYXcgZmlsZXMvQXJqdW5fUGFyZXRoby9tZXRhZGF0YS5jc3YiKQptZXRhCmBgYAoKQ29vbCAtIGxldCdzIHRyeSB0byBmdXNlIGl0IGFsbCB0b2dldGhlcjoKCmBgYHtyfQpkaW0oUGFyZXRvXzAxKQpkaW0oUGFyZXRvXzAyKQpkaW0obWV0YSkKZGltKGFsbF9NUjMpCmBgYAoKb2sgLSBzbyBmb3Igc29tZSByZWFzb24gd2UgZG8gaGF2ZSBsZXNzIHBhcmV0aG8gY2FsY3VsYXRlZCB0aGFuIGFjdHVhbGx5IHBsYW50cywgYnV0IHRoYXQncyBvayBhdCB0aGlzIHBvaW50LiAKCkxldCdzIGZpcnN0IGZ1c2UgdHdvIHBhcmV0aG8gZmlsZXM6CgpgYGB7cn0KUGFyZXRvX2FsbCA8LSBtZXJnZShQYXJldG9fMDEsIFBhcmV0b18wMiwgYnk9ImFyYm9yLm5hbWUiKQpkaW0oUGFyZXRvX2FsbCkKaGVhZChQYXJldG9fYWxsKQpgYGAKClRoZW4gYWRkIG1ldGEtZGF0YQoKYGBge3J9CnVuaXF1ZShQYXJldG9fYWxsJGFyYm9yLm5hbWUpCnVuaXF1ZShtZXRhJGFyYm9yLm5hbWUpCgpQYXJldG9fYWxsJGFyYm9yLm5hbWUgPC0gZ3N1YigiICIsICIiLCBQYXJldG9fYWxsJGFyYm9yLm5hbWUpCm1ldGEkYXJib3IubmFtZSA8LSBnc3ViKCIgIiwgIiIsIG1ldGEkYXJib3IubmFtZSkKClBhcmV0b19tZXRhIDwtIG1lcmdlKFBhcmV0b19hbGwsIG1ldGEsIGJ5PSJhcmJvci5uYW1lIikKUGFyZXRvX21ldGEKZGltKFBhcmV0b19tZXRhKQpgYGAKCkxldCdzIGNsZWFuIHVwIHRoaXMgcGFyZXRvX21ldGEgZmlsZToKCmBgYHtyfQpjb2xuYW1lcyhQYXJldG9fbWV0YSkKUGFyZXRvIDwtIFBhcmV0b19tZXRhWyxjKDg6MTMsIDE6NSldCmRpbShQYXJldG8pCmNvbG5hbWVzKFBhcmV0bylbMTFdIDwtICJwYXJldG8uZnJvbnQuc2NhbGluZy5sb2NhdGlvbiIKUGFyZXRvCmBgYAoKTm93IC0gbGV0J3MgdHJ5IGFuZCBjb25uZWN0IGl0IHRvIHRoZSBNUl9hbGwzIGZpbGU6CgpgYGB7cn0KYWxsX01SMwp1bmlxdWUoYWxsX01SMyRnZW5vdHlwZSkKYWxsX01SMyRhcmJvci5uYW1lIDwtIHBhc3RlKGFsbF9NUjMkZ2Vub3R5cGUsICJfIiwgYWxsX01SMyRyZXAsICJfIiwgYWxsX01SMyRjb25kLCAiX0RBUyIsIGFsbF9NUjMkREFTLCBzZXA9IiIpCmhlYWQoYWxsX01SMykKCmFsbF9NUjMkYXJib3IubmFtZSA8LSBnc3ViKCJEQVMwIiwgImRheTEiLCBhbGxfTVIzJGFyYm9yLm5hbWUpCmFsbF9NUjMkYXJib3IubmFtZSA8LSBnc3ViKCJEQVMxIiwgImRheTIiLCBhbGxfTVIzJGFyYm9yLm5hbWUpCmFsbF9NUjMkYXJib3IubmFtZSA8LSBnc3ViKCJEQVMyIiwgImRheTMiLCBhbGxfTVIzJGFyYm9yLm5hbWUpCmFsbF9NUjMkYXJib3IubmFtZSA8LSBnc3ViKCJEQVMzIiwgImRheTQiLCBhbGxfTVIzJGFyYm9yLm5hbWUpCmFsbF9NUjMkYXJib3IubmFtZSA8LSBnc3ViKCJEQVM0IiwgImRheTUiLCBhbGxfTVIzJGFyYm9yLm5hbWUpCmFsbF9NUjMkYXJib3IubmFtZSA8LSBnc3ViKCIgIiwgIiIsIGFsbF9NUjMkYXJib3IubmFtZSkKaGVhZChhbGxfTVIzKQp1bmlxdWUoYWxsX01SMyRhcmJvci5uYW1lKSAlaW4lIHVuaXF1ZShQYXJldG8kYXJib3IubmFtZSkKYWxsX01SNCA8LSBtZXJnZShhbGxfTVIzLCBQYXJldG8sIGJ5PSJhcmJvci5uYW1lIikKZGltKGFsbF9NUjQpCmFsbF9NUjQKYGBgCgpMZXQncyBjbGVhbiBpdCB1cCBhIGxpdHRsZSBiZWZvcmUgZ29pbmcgZnVydGhlcjoKCmBgYHtyfQpjb2xuYW1lcyhhbGxfTVI0KQoKYWxsX01SNCA8LSBhbGxfTVI0WyxjKDE6NjUsNzI6NzUpXQpjb2xuYW1lcyhhbGxfTVI0KVs1XSA8LSAiZXhwZXJpbWVudCIKY29sbmFtZXMoYWxsX01SNClbN10gPC0gImdlbm90eXBlIgphbGxfTVI0CmBgYAoKIyMjIFBhcmV0byB0aHJvdWdoIHRpbWU6CgpOb3cgd2UgaGF2ZSBhbGwgdGhlIGRhdGEgLSBsZXQncyBoYXZlIGEgbG9vayBhdCBob3cgdGhhdCBpcyBsb29raW5nIHRocm91Z2ggdGltZToKCmBgYHtyfQphbGxfTVI1IDwtIG5hLm9taXQoYWxsX01SNCkKYWxsX01SNSREQVMgPC0gYXMuZmFjdG9yKGFsbF9NUjUkREFTKQoKUEZkaXN0X2xncmFwaCA8LSBnZ3Bsb3QoZGF0YT1hbGxfTVI1LCBhZXMoeD0gREFTLCB5PXBhcmV0by5mcm9udC5kaXN0YW5jZSwgZ3JvdXAgPSByb290X25hbWUsIGNvbG9yID0gY29uZCkpIApQRmRpc3RfbGdyYXBoIDwtIFBGZGlzdF9sZ3JhcGggK2dlb21fbGluZShhbHBoYSA9IDAuMSkgClBGZGlzdGFuY2VfbGdyYXBoIDwtIFBGZGlzdGFuY2VfbGdyYXBoICsgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gbWVhbl9zZSwgZ2VvbT0icmliYm9uIiwgbGluZXR5cGU9MCwgYWVzKGdyb3VwPWNvbmQpLCBhbHBoYT0wLjMpClBGZGlzdGFuY2VfbGdyYXBoIDwtIFBGZGlzdGFuY2VfbGdyYXBoICsgc3RhdF9zdW1tYXJ5KGZ1bi55PW1lYW4sIGFlcyhncm91cD0gY29uZCksICBzaXplPTAuNywgZ2VvbT0ibGluZSIsIGxpbmV0eXBlID0gImRhc2hlZCIpClBGZGlzdGFuY2VfbGdyYXBoIDwtIFBGZGlzdGFuY2VfbGdyYXBoICsgc3RhdF9jb21wYXJlX21lYW5zKGFlcyhncm91cCA9IGNvbmQpLCBsYWJlbCA9ICJwLnNpZ25pZiIsIG1ldGhvZCA9ICJ0LnRlc3QiLCBoaWRlLm5zID0gVCkKClBGZGlzdGFuY2VfbGdyYXBoIDwtIFBGZGlzdGFuY2VfbGdyYXBoICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJzdGVlbGJsdWUiLCAiZmlyZWJyaWNrMyIpKSArIGdndGl0bGUoIkluZGl2aWR1YWwgYWNjZXNzaW9ucyIpClBGZGlzdGFuY2VfbGdyYXBoIDwtIFBGZGlzdGFuY2VfbGdyYXBoICsgeWxhYigiUGFyZXRvIEZyb250IERpc3RhbmNlIChhLnUuKSIpICsgeGxhYigiRGF5cyBBZnRlciBTdHJlc3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScpClBGZGlzdGFuY2VfbGdyYXBoCmBgYAoKYGBge3J9ClBGc2NkaXN0X2xncmFwaCA8LSBnZ3Bsb3QoZGF0YT1hbGxfTVI1LCBhZXMoeD0gREFTLCB5PXBhcmV0by5mcm9udC5zY2FsaW5nLmRpc3RhbmNlLCBncm91cCA9IHJvb3RfbmFtZSwgY29sb3IgPSBjb25kKSkgClBGc2NkaXN0X2xncmFwaCA8LSBQRnNjZGlzdF9sZ3JhcGggK2dlb21fbGluZShhbHBoYSA9IDAuMSkgClBGc2NkaXN0X2xncmFwaCA8LSBQRnNjZGlzdF9sZ3JhcGggKyBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NlLCBnZW9tPSJyaWJib24iLCBsaW5ldHlwZT0wLCBhZXMoZ3JvdXA9Y29uZCksIGFscGhhPTAuMykKUEZzY2Rpc3RfbGdyYXBoIDwtIFBGc2NkaXN0X2xncmFwaCArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpQRnNjZGlzdF9sZ3JhcGggPC0gUEZzY2Rpc3RfbGdyYXBoICsgc3RhdF9jb21wYXJlX21lYW5zKGFlcyhncm91cCA9IGNvbmQpLCBsYWJlbCA9ICJwLnNpZ25pZiIsIG1ldGhvZCA9ICJ0LnRlc3QiLCBoaWRlLm5zID0gVCkKClBGc2NkaXN0X2xncmFwaCA8LSBQRnNjZGlzdF9sZ3JhcGggKyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoInN0ZWVsYmx1ZSIsICJmaXJlYnJpY2szIikpICsgZ2d0aXRsZSgiSW5kaXZpZHVhbCBhY2Nlc3Npb25zIikKUEZzY2Rpc3RfbGdyYXBoIDwtIFBGc2NkaXN0X2xncmFwaCArIHlsYWIoIlBhcmV0byBGcm9udCBTY2FsaW5nIERpc3RhbmNlIChhLnUuKSIpICsgeGxhYigiRGF5cyBBZnRlciBTdHJlc3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScpClBGc2NkaXN0X2xncmFwaApgYGAKCgpgYGB7cn0KUEZsb2NfbGdyYXBoIDwtIGdncGxvdChkYXRhPWFsbF9NUjUsIGFlcyh4PSBEQVMsIHk9cGFyZXRvLmZyb250LmxvY2F0aW9uLCBncm91cCA9IHJvb3RfbmFtZSwgY29sb3IgPSBjb25kKSkgClBGbG9jX2xncmFwaCA8LSBQRmxvY19sZ3JhcGggK2dlb21fbGluZShhbHBoYSA9IDAuMSkgClBGbG9jX2xncmFwaCA8LSBQRmxvY19sZ3JhcGggKyBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NlLCBnZW9tPSJyaWJib24iLCBsaW5ldHlwZT0wLCBhZXMoZ3JvdXA9Y29uZCksIGFscGhhPTAuMykKUEZsb2NfbGdyYXBoIDwtIFBGbG9jX2xncmFwaCArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpQRmxvY19sZ3JhcGggPC0gUEZsb2NfbGdyYXBoICsgc3RhdF9jb21wYXJlX21lYW5zKGFlcyhncm91cCA9IGNvbmQpLCBsYWJlbCA9ICJwLnNpZ25pZiIsIG1ldGhvZCA9ICJ0LnRlc3QiLCBoaWRlLm5zID0gVCkKUEZsb2NfbGdyYXBoIDwtIFBGbG9jX2xncmFwaCArIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gYygic3RlZWxibHVlIiwgImZpcmVicmljazMiKSkgKyBnZ3RpdGxlKCJJbmRpdmlkdWFsIGFjY2Vzc2lvbnMiKQpQRmxvY19sZ3JhcGggPC0gUEZsb2NfbGdyYXBoICsgeWxhYigiUGFyZXRvIEZyb250IExvY2F0aW9uIChhLnUuKSIpICsgeGxhYigiRGF5cyBBZnRlciBTdHJlc3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScpClBGbG9jX2xncmFwaApgYGAKCmBgYHtyfQpQRnNjbG9jX2xncmFwaCA8LSBnZ3Bsb3QoZGF0YT1hbGxfTVI1LCBhZXMoeD0gREFTLCB5PXBhcmV0by5mcm9udC5zY2FsaW5nLmxvY2F0aW9uLCBncm91cCA9IHJvb3RfbmFtZSwgY29sb3IgPSBjb25kKSkgClBGc2Nsb2NfbGdyYXBoIDwtIFBGc2Nsb2NfbGdyYXBoICtnZW9tX2xpbmUoYWxwaGEgPSAwLjEpIApQRnNjbG9jX2xncmFwaCA8LSBQRnNjbG9jX2xncmFwaCArIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IG1lYW5fc2UsIGdlb209InJpYmJvbiIsIGxpbmV0eXBlPTAsIGFlcyhncm91cD1jb25kKSwgYWxwaGE9MC4zKQpQRnNjbG9jX2xncmFwaCA8LSBQRnNjbG9jX2xncmFwaCArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpQRnNjbG9jX2xncmFwaCA8LSBQRnNjbG9jX2xncmFwaCArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpClBGc2Nsb2NfbGdyYXBoIDwtIFBGc2Nsb2NfbGdyYXBoICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJzdGVlbGJsdWUiLCAiZmlyZWJyaWNrMyIpKSArIGdndGl0bGUoIkluZGl2aWR1YWwgYWNjZXNzaW9ucyIpClBGc2Nsb2NfbGdyYXBoIDwtIFBGc2Nsb2NfbGdyYXBoICsgeWxhYigiUGFyZXRvIEZyb250IFNjYWxpbmcgTG9jYXRpb24gKGEudS4pIikgKyB4bGFiKCJEYXlzIEFmdGVyIFN0cmVzcyIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSdub25lJykKUEZzY2xvY19sZ3JhcGgKYGBgCgpvayAtIG5vdyBsZXQncyBoYXZlIGEgbG9vayB3aGF0IGlzIHRoZSByZXByb2R1Y2liaWxpdHkgb2YgdGhlIHBhcmV0byBmcm9udCBsb2NhdGlvbiB3aXRoaW4gdGhlIGdlbm90eXBlOgoKYGBge3J9CmludGVyZXN0aW5nIDwtIHN1YnNldChhbGxfTVI1LCBhbGxfTVI1JGdlbm90eXBlID09ICIgMjQ4IikKaW50ZXJlc3RpbmcKCk0yNDhfUEZTY2xvYyA8LSBnZ3Bsb3QoZGF0YT1pbnRlcmVzdGluZywgYWVzKHg9IERBUywgeT1wYXJldG8uZnJvbnQuc2NhbGluZy5sb2NhdGlvbiwgZ3JvdXAgPSByb290X25hbWUsIGNvbG9yID0gY29uZCkpIApNMjQ4X1BGU2Nsb2MgPC0gTTI0OF9QRlNjbG9jICtnZW9tX2xpbmUoYWxwaGEgPSAwLjIpIApNMjQ4X1BGU2Nsb2MgPC0gTTI0OF9QRlNjbG9jICsgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gbWVhbl9zZSwgZ2VvbT0icmliYm9uIiwgbGluZXR5cGU9MCwgYWVzKGdyb3VwPWNvbmQpLCBhbHBoYT0wLjMpCk0yNDhfUEZTY2xvYyA8LSBNMjQ4X1BGU2Nsb2MgKyBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgYWVzKGdyb3VwPSBjb25kKSwgIHNpemU9MC43LCBnZW9tPSJsaW5lIiwgbGluZXR5cGUgPSAiZGFzaGVkIikKTTI0OF9QRlNjbG9jIDwtIE0yNDhfUEZTY2xvYyArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCk0yNDhfUEZTY2xvYyA8LSBNMjQ4X1BGU2Nsb2MgKyBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoInN0ZWVsYmx1ZSIsICJmaXJlYnJpY2szIikpICsgZ2d0aXRsZSgiTTI0OCIpCk0yNDhfUEZTY2xvYyA8LSBNMjQ4X1BGU2Nsb2MgKyB5bGFiKCJQYXJldG8gRnJvbnQgU2NhbGluZyBMb2NhdGlvbiIpICsgeGxhYigiRGF5cyBBZnRlciBTdHJlc3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScpCk0yNDhfUEZTY2xvYwpgYGAKCkxldCdzIHNhdmUgdGhpcyBmaWxlIGFuZCBleHBsb3JlIHRoZSBoZXJpdGFiaWxpdHkgb2YgdGhlc2UgdHJhaXRzIGluIE1WQXBwOgoKYGBge3J9CndyaXRlLmNzdihhbGxfTVI1LCAiQmlnMDF0bzA0X2luY2wuUEYuY3N2Iiwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKVGhlIGhlcml0YWJpaXR5IG9mIGFsbCB0aGUgdHJhaXRzIGlzIHByZXR0eSBkZWNlbnQgb3ZlcmFsbCAtIGJldHdlZW4gMC40IGFuZCAwLjcgaW4gbW9zdCBjYXNlcy4gCgpMZXQncyBzZWUgaG93IHRoZSBQYXJldG8gRnJvbnQgU2NhbGluZyBMb2NhdGlvbiBpcyBjb3JyZWxhdGVkIHdpdGggTFIgdHJhaXRzOgoKYGBge3J9CmFsbF9NUjUkREFTIDwtIGFzLmZhY3RvcihhbGxfTVI1JERBUykKUEZzYy5sb2NfdnNfVFJTIDwtIGdnc2NhdHRlcihhbGxfTVI1LCB4ID0gInBhcmV0by5mcm9udC5zY2FsaW5nLmxvY2F0aW9uIiwgeSA9ICJUUlMiLCBjb2xvciA9ICJjb25kIiwgc2l6ZSA9IDAuMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWcgPSBUUlVFLCBmYWNldC5ieSA9ICJEQVMiKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikKUEZzYy5sb2NfdnNfVFJTCmBgYAoKYGBge3J9ClBGc2MubG9jX3ZzX0xSbm8gPC0gZ2dzY2F0dGVyKGFsbF9NUjUsIHggPSAicGFyZXRvLmZyb250LnNjYWxpbmcubG9jYXRpb24iLCB5ID0gIkxSbm8iLCBjb2xvciA9ICJjb25kIiwgc2l6ZSA9IDAuMywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBydWcgPSBUUlVFLCBmYWNldC5ieSA9ICJEQVMiKSArIHN0YXRfY29yKG1ldGhvZCA9ICJwZWFyc29uIikKUEZzYy5sb2NfdnNfTFJubwpgYGAKCgpgYGB7cn0KUEZzYy5sb2NfdnNfYUxSTCA8LSBnZ3NjYXR0ZXIoYWxsX01SNSwgeCA9ICJwYXJldG8uZnJvbnQuc2NhbGluZy5sb2NhdGlvbiIsIHkgPSAiYUxSTCIsIGNvbG9yID0gImNvbmQiLCBzaXplID0gMC4zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsIGZhY2V0LmJ5ID0gIkRBUyIpICsgc3RhdF9jb3IobWV0aG9kID0gInBlYXJzb24iKQpQRnNjLmxvY192c19hTFJMCmBgYAoKYGBge3J9ClBGc2MubG9jX3ZzX0NvRyA8LSBnZ3NjYXR0ZXIoYWxsX01SNSwgeCA9ICJwYXJldG8uZnJvbnQuc2NhbGluZy5sb2NhdGlvbiIsIHkgPSAiQ29HIiwgY29sb3IgPSAiY29uZCIsIHNpemUgPSAwLjMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVnID0gVFJVRSwgZmFjZXQuYnkgPSAiREFTIikgKyBzdGF0X2NvcihtZXRob2QgPSAicGVhcnNvbiIpClBGc2MubG9jX3ZzX0NvRwpgYGAKCmFjdHVhbGx5IC0gQ29HIHNob3VsZCBiZSBjYWxjdWxhdGVkIGFzIHBlcmMuIG9yIE1SIC0gSSB3b25kZXIgd2h5IEkgZGlkbnQgZG8gdGhhdCBiZWZvcmUgOikKCmBgYHtyfQpjb2xuYW1lcyhhbGxfTVI1KQphbGxfTVI1JENvRy5wZXIgPC0gYWxsX01SNSRDb0cgLyBhbGxfTVI1JE1STAoKQ29HcGVyY19sZ3JhcGggPC0gZ2dwbG90KGRhdGE9YWxsX01SNSwgYWVzKHg9IERBUywgeT1Db0cucGVyLCBncm91cCA9IHJvb3RfbmFtZSwgY29sb3IgPSBjb25kKSkgCkNvR3BlcmNfbGdyYXBoIDwtIENvR3BlcmNfbGdyYXBoICtnZW9tX2xpbmUoYWxwaGEgPSAwLjEpIApDb0dwZXJjX2xncmFwaCA8LSBDb0dwZXJjX2xncmFwaCArIHN0YXRfc3VtbWFyeShmdW4uZGF0YSA9IG1lYW5fc2UsIGdlb209InJpYmJvbiIsIGxpbmV0eXBlPTAsIGFlcyhncm91cD1jb25kKSwgYWxwaGE9MC4zKQpDb0dwZXJjX2xncmFwaCA8LSBDb0dwZXJjX2xncmFwaCArIHN0YXRfc3VtbWFyeShmdW4ueT1tZWFuLCBhZXMoZ3JvdXA9IGNvbmQpLCAgc2l6ZT0wLjcsIGdlb209ImxpbmUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKQpDb0dwZXJjX2xncmFwaCA8LSBDb0dwZXJjX2xncmFwaCArIHN0YXRfY29tcGFyZV9tZWFucyhhZXMoZ3JvdXAgPSBjb25kKSwgbGFiZWwgPSAicC5zaWduaWYiLCBtZXRob2QgPSAidC50ZXN0IiwgaGlkZS5ucyA9IFQpCkNvR3BlcmNfbGdyYXBoIDwtIENvR3BlcmNfbGdyYXBoICsgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCJzdGVlbGJsdWUiLCAiZmlyZWJyaWNrMyIpKSArIGdndGl0bGUoIkluZGl2aWR1YWwgYWNjZXNzaW9ucyIpCkNvR3BlcmNfbGdyYXBoIDwtIENvR3BlcmNfbGdyYXBoICsgeWxhYigiRnJhY3Rpb24gb2YgdGhlIE1haW4gUm9vdCIpICsgeGxhYigiRGF5cyBBZnRlciBTdHJlc3MiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0nbm9uZScpCkNvR3BlcmNfbGdyYXBoCgpQRnNjLmxvY192c19Db0cucGVyYyA8LSBnZ3NjYXR0ZXIoYWxsX01SNSwgeCA9ICJwYXJldG8uZnJvbnQuc2NhbGluZy5sb2NhdGlvbiIsIHkgPSAiQ29HLnBlciIsIGNvbG9yID0gImNvbmQiLCBzaXplID0gMC4zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ1ZyA9IFRSVUUsIGZhY2V0LmJ5ID0gIkRBUyIpICsgc3RhdF9jb3IobWV0aG9kID0gInBlYXJzb24iKQpQRnNjLmxvY192c19Db0cucGVyYwpgYGAKCkFsc28gLSBJIHdvdWxkIGxpa2UgdG8gaGF2ZSBhIGxvb2sgYXQgaG93IHRoaXMgc2NhbGluZy5sb2NhdGlvbiBsb29rcyBhY3Jvc3MgdGhlIGFjY2Vzc2lvbnMgd2l0aGluIG9uZSBkYXkgYW5kIGJldHdlZW4gY29uZGl0aW9ucyAtIGxldHMgZG8gREFTNAoKYGBge3J9CkRBUzQgPC0gc3Vic2V0KGFsbF9NUjUsIGFsbF9NUjUkREFTID09IDQpCgpncmFuZC5tZWFucyA8LSBhZ2dyZWdhdGUocGFyZXRvLmZyb250LnNjYWxpbmcubG9jYXRpb24gfiBjb25kLCBkYXRhID0gREFTNCwgRlVOID0gbWVhbikKZ3JhbmQubWVhbnMKCnVuaXF1ZShEQVM0JGdlbm90eXBlKQoKUEYuc2MubG9jX3BfZ2VubyA8LSBnZ2Vycm9ycGxvdChEQVM0LCB5ID0gInBhcmV0by5mcm9udC5zY2FsaW5nLmxvY2F0aW9uIiwgeCA9ICJnZW5vdHlwZSIsIGZpbGw9Imdlbm90eXBlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPSJnZW5vdHlwZSIsIGZhY2V0LmJ5ID0gYygiY29uZCIpLCBuY29sPTEsIGRlc2Nfc3RhdCA9ICJtZWFuX3NkIiwgYWRkID0gImppdHRlciIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkLnBhcmFtcyA9IGxpc3QoY29sb3IgPSAiZGFya2dyYXkiKSwgeGxhYj0iR2Vub3R5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWI9IlBhcmV0byBGcm9udCBTY2FsaW5nIExvY2F0aW9uIChhLnUuKSIpIApQRi5zYy5sb2NfcF9nZW5vIDwtIFBGLnNjLmxvY19wX2dlbm8gKyBnZW9tX2hsaW5lKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBncmFuZC5tZWFucywgYWVzKHlpbnRlcmNlcHQgPSBwYXJldG8uZnJvbnQuc2NhbGluZy5sb2NhdGlvbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZXR5cGUgPSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwID0gImNvbmQiKQpQRi5zYy5sb2NfcF9nZW5vIDwtIFBGLnNjLmxvY19wX2dlbm8gKyBycmVtb3ZlKCJsZWdlbmQiKSArIHN0YXRfY29tcGFyZV9tZWFucyhtZXRob2Q9InQudGVzdCIsIHJlZi5ncm91cCA9ICIuYWxsLiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsID0gInAuc2lnbmlmIiwgaGlkZS5ucyA9IFQpClBGLnNjLmxvY19wX2dlbm8KCmBgYAoKTGV0J3MgY2FsY3VsYXRlIHRoZSBjaGFuZ2UgaW4gdGhlIHBhcmV0byBmcm9udCBzY2FsaW5nIGxvY2F0aW9uIHJlbGF0aXZlIHRvIGNvbnRyb2wgY29uZGl0aW9ucyBwZXIgYWNjZXNzaW9uIGFzIHdlbGwuCgpgYGB7cn0KREFTNF9hdmcgPC0gc3VtbWFyeUJ5KGRhdGEgPSBEQVM0LCBwYXJldG8uZnJvbnQuc2NhbGluZy5sb2NhdGlvbiB+IGdlbm90eXBlICsgY29uZCkKREFTNF9hdmcKREFTX0MgPC0gc3Vic2V0KERBUzRfYXZnLCBEQVM0X2F2ZyRjb25kID09ICJDIikKREFTX0MgPC0gREFTX0NbLGMoMSwzKV0KY29sbmFtZXMoREFTX0MpWzJdIDwtICJQRi5zY2FsaW5nLmxvY2F0aW9uLkNvbnRyb2wiCkRBU19TIDwtIHN1YnNldChEQVM0X2F2ZywgREFTNF9hdmckY29uZCA9PSAiUyIpCkRBU19TIDwtIERBU19TWyxjKDEsMyldCmNvbG5hbWVzKERBU19TKVsyXSA8LSAiUEYuc2NhbGluZy5sb2NhdGlvbi5TYWx0IgoKREFTX1NUSSA8LSBtZXJnZShEQVNfQywgREFTX1MsIGlkPSJnZW5vdHlwZSIpCkRBU19TVEkkU1RJIDwtIERBU19TVEkkUEYuc2NhbGluZy5sb2NhdGlvbi5TYWx0IC8gREFTX1NUSSRQRi5zY2FsaW5nLmxvY2F0aW9uLkNvbnRyb2wKREFTX1NUSQpgYGAKCmBgYHtyfQpQRi5zYy5sb2NfU1RJX2hpc3RvIDwtIGdnaGlzdG9ncmFtKERBU19TVEksIHggPSAiU1RJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkID0gIm1lYW4iLCBydWcgPSBUUlVFKSArIHhsYWIoIlNhbHQgLyBDb250cm9sIikKUEYuc2MubG9jX1NUSV9oaXN0bwoKREFTNF9hdmcKClBGLnNjLmxvY19oaXN0byA8LSBnZ2hpc3RvZ3JhbShEQVM0X2F2ZywgeCA9ICJwYXJldG8uZnJvbnQuc2NhbGluZy5sb2NhdGlvbi5tZWFuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGQgPSAibWVhbiIsIHJ1ZyA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiY29uZCIsIGZpbGwgPSAiY29uZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFsZXR0ZSA9IGMoIiMwMEFGQkIiLCAiI0U3QjgwMCIpKSArIHhsYWIoIlBhcmV0byBGcm9udCBTY2FsaW5nIExvY2F0aW9uIikKUEYuc2MubG9jX2hpc3RvCgpQRi5zYy5sb2NfaGlzdG8gPC0gZ2doaXN0b2dyYW0oYWxsX01SNSwgeCA9ICJwYXJldG8uZnJvbnQuc2NhbGluZy5sb2NhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkID0gIm1lYW4iLCBydWcgPSBUUlVFLCBmYWNldC5ieSA9ICJEQVMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gImNvbmQiLCBmaWxsID0gImNvbmQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwgIiNFN0I4MDAiKSkgKyB4bGFiKCJQYXJldG8gRnJvbnQgU2NhbGluZyBMb2NhdGlvbiIpClBGLnNjLmxvY19oaXN0bwpgYGAKCg==